Compare commits

..

14 Commits

Author SHA1 Message Date
Thomas Schönauer
d7182b5a6e v11.0.0 bump (#410) 2023-04-30 19:02:26 +00:00
Thomas Schönauer
93ec1172fe Update README.md 2023-04-30 18:58:22 +00:00
Thomas Schönauer
609477a373 Update README.md 2023-04-30 18:57:23 +00:00
Thomas Schönauer
1d49af10a7 Update README.md 2023-04-30 18:57:07 +00:00
Utkarsh Gupta
327ed837c2 Replace directories with home & etcetera (#407)
* Use global lazy HOME_DIR

* Remove unused base_dirs

* Use `etcetera` instead of `directories`

---------

Co-authored-by: Thomas Schönauer <37108907+DottoDev@users.noreply.github.com>
2023-04-30 18:32:13 +00:00
Thomas Schönauer
d406e2aeab Assume Fedora Silverblue based on os-release and not on existence of rpm-ostree (#393)
* Do not assume silverblue if rpm-ostree is available

* Fix typo

* Fix config error
2023-04-30 18:22:08 +00:00
dependabot[bot]
0991cc8a6f Bump enumflags2 from 0.7.5 to 0.7.7 (#408) 2023-04-24 20:37:00 +00:00
Brian Riccardi
ac6330fac8 Added support to 'mamba' (alternative to 'conda' with the exact same commands/interface) (#395) 2023-04-17 14:19:59 +00:00
dependabot[bot]
29f0d229d3 Bump h2 from 0.3.16 to 0.3.17 (#404) 2023-04-17 14:19:48 +00:00
Roey Darwish Dror
3dd11f7b52 No need to run self-update in Rustup (#403) 2023-04-05 12:42:47 +00:00
Roey Darwish Dror
ddb1a021bb Display the preamble in Linux only if notify-send is installed (#401) 2023-04-05 12:34:47 +00:00
PolpOnline
565aa405be Add no-self-update config and flag (#388) 2023-03-22 21:05:21 +00:00
Utkarsh Gupta
907465f891 run_custom_command: allow using interactive shell on unix (#383) 2023-03-17 16:28:58 +00:00
Trevor Sullivan
250485c826 Add Scoop manifest link for Windows installation (#384) 2023-03-15 07:40:31 +00:00
17 changed files with 375 additions and 235 deletions

162
Cargo.lock generated
View File

@@ -119,7 +119,7 @@ checksum = "d7d78656ba01f1b93024b7c3a0467f1608e4be67d725749fdcd7d2c7678fd7a2"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -136,7 +136,7 @@ checksum = "b84f9ebcc6c1f5b8cb160f6990096a5c127f423fcb6e1ccc46c370cbdfb75dfc"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -270,7 +270,7 @@ dependencies = [
"proc-macro-error",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -399,7 +399,7 @@ dependencies = [
"proc-macro2",
"quote",
"scratch",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -416,7 +416,7 @@ checksum = "0b75aed41bb2e6367cae39e6326ef817a851db13c13e4f3263714ca3cfb8de56"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -427,16 +427,7 @@ checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "directories"
version = "4.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f51c5d4ddabd36886dd3e1438cb358cdcb0d7c499cb99cb4ac2e38e18b5cb210"
dependencies = [
"dirs-sys",
"syn 1.0.109",
]
[[package]]
@@ -509,9 +500,9 @@ dependencies = [
[[package]]
name = "enumflags2"
version = "0.7.5"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e75d4cd21b95383444831539909fbb14b9dc3fdceb2a6f5d36577329a1f55ccb"
checksum = "c041f5090df68b32bcd905365fd51769c8b9d553fe87fde0b683534f10c01bd2"
dependencies = [
"enumflags2_derive",
"serde",
@@ -519,13 +510,24 @@ dependencies = [
[[package]]
name = "enumflags2_derive"
version = "0.7.4"
version = "0.7.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f58dc3c5e468259f19f2d46304a6b28f1c3d034442e14b322d2b850e36f6d5ae"
checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745"
dependencies = [
"proc-macro2",
"quote",
"syn",
"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]]
@@ -661,7 +663,7 @@ checksum = "3eb14ed937631bd8b8b8977f2c198443447a8355b6e3ca599f38c975e5a963b6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -719,9 +721,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b"
[[package]]
name = "h2"
version = "0.3.16"
version = "0.3.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5be7b54589b581f624f566bf5d8eb2bab1db736c51528720b6bd36b96b55924d"
checksum = "66b91535aa35fea1523ad1b86cb6b53c28e0ae566ba4a460f4457e936cad7c6f"
dependencies = [
"bytes",
"fnv",
@@ -1336,7 +1338,7 @@ dependencies = [
"proc-macro-error-attr",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"version_check",
]
@@ -1656,7 +1658,7 @@ checksum = "d071a94a3fac4aff69d023a7f411e33f40f3483f8c5190b1953822b6b76d7630"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -1678,7 +1680,7 @@ checksum = "395627de918015623b32e7669714206363a7fc00382bf477e72c1f7533e8eafc"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -1811,7 +1813,7 @@ dependencies = [
"heck 0.3.3",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -1824,7 +1826,7 @@ dependencies = [
"proc-macro2",
"quote",
"rustversion",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -1838,6 +1840,17 @@ dependencies = [
"unicode-ident",
]
[[package]]
name = "syn"
version = "2.0.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "79d9531f94112cfc3e4c8f5f02cb2b58f72c97b7efd85f70203cc6d8efda5927"
dependencies = [
"proc-macro2",
"quote",
"unicode-ident",
]
[[package]]
name = "tar"
version = "0.4.38"
@@ -1906,7 +1919,7 @@ checksum = "5420d42e90af0c38c3290abcca25b9b3bdf379fc9f55c528f53a269d9c9a267e"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -2051,7 +2064,7 @@ dependencies = [
"clap_mangen",
"color-eyre",
"console",
"directories",
"etcetera",
"futures",
"glob",
"home",
@@ -2059,6 +2072,7 @@ dependencies = [
"libc",
"nix 0.24.3",
"notify-rust",
"once_cell",
"parselnk",
"regex",
"rust-ini",
@@ -2106,7 +2120,7 @@ checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -2297,7 +2311,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"wasm-bindgen-shared",
]
@@ -2331,7 +2345,7 @@ checksum = "2aff81306fcac3c7515ad4e177f521b5c9a15f2b08f4e32d823066102f35a5f6"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -2437,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",
]
@@ -2452,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]]
@@ -2461,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"
@@ -2488,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"
@@ -2500,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"
@@ -2512,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"
@@ -2524,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"
@@ -2542,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"
@@ -2619,7 +2699,7 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
"syn",
"syn 1.0.109",
]
[[package]]
@@ -2669,7 +2749,7 @@ dependencies = [
"proc-macro-crate",
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
"zvariant_utils",
]
@@ -2681,5 +2761,5 @@ checksum = "53b22993dbc4d128a17a3b6c92f1c63872dd67198537ee728d8b5d7c40640a8b"
dependencies = [
"proc-macro2",
"quote",
"syn",
"syn 1.0.109",
]

View File

@@ -5,7 +5,7 @@ categories = ["os"]
keywords = ["upgrade", "update"]
license = "GPL-3.0"
repository = "https://github.com/topgrade-rs/topgrade"
version = "10.3.3"
version = "11.0.0"
authors = ["Roey Darwish Dror <roey.ghost@gmail.com>", "Thomas Schönauer <t.schoenauer@hgs-wt.at>"]
exclude = ["doc/screenshot.gif"]
edition = "2021"
@@ -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" }

View File

@@ -10,7 +10,12 @@
<img alt="Demo" src="doc/screenshot.gif" width="550px">
</div>
## Maintainers Wanted
I currently have not enough time to maintain this project on the level required and which the project deserves. For this reason I'm asking the community to help supporting the project, to help and work on resolving issues and create new features. Thanks for all your help.
## Introduction
> **Note**
@@ -28,6 +33,7 @@ To remedy this, **Topgrade** detects which tools you use and runs the appropriat
- NixOS: [Nixpkgs](https://search.nixos.org/packages?show=topgrade)
- Void Linux: [XBPS](https://voidlinux.org/packages/?arch=x86_64&q=topgrade)
- macOS: [Homebrew](https://formulae.brew.sh/formula/topgrade) or [MacPorts](https://ports.macports.org/port/topgrade/)
- Windows: [Scoop](https://github.com/ScoopInstaller/Main/blob/master/bucket/topgrade.json)
Other systems users can either use `cargo install` or the compiled binaries from the release page.
The compiled binaries contain a self-upgrading feature.
@@ -43,7 +49,7 @@ Visit the documentation at [topgrade-rs.github.io](https://topgrade-rs.github.io
> **Warning**
> Work in Progress
## Customization
## Configuration
See `config.example.toml` for an example configuration file.
@@ -54,6 +60,14 @@ The configuration should be placed in the following paths depending on the opera
- **Windows** - `%APPDATA%/topgrade.toml`
- **macOS** and **other Unix systems** - `${XDG_CONFIG_HOME:-~/.config}/topgrade.toml`
### Custom Commands
Custom commands can be defined in the config file which can be run before, during, or after the inbuilt commands, as required.
By default, the custom commands are run using a new shell according to the `$SHELL` environment variable on unix (falls back to `sh`) or `pwsh` on windows (falls back to `powershell`).
On unix, if you want to run your command using an interactive shell, for example to source your shell's rc files, you can add `-i` at the start of your custom command.
But note that this requires the command to exit the shell correctly or else the shell will hang indefinitely.
## Remote Execution
You can specify a key called `remote_topgrades` in the configuration file.

View File

@@ -50,6 +50,9 @@
# Skip the preamble displayed when topgrade is run
#display_preamble = false
# Whether to self update (this is ignored if the binary has been built without self update support, available also via setting the environment variable TOPGRADE_NO_SELF_UPGRADE)
#no_self_update = true
[git]
#max_concurrency = 5
# Additional git repositories to pull
@@ -74,6 +77,7 @@
# Custom commands
[commands]
#"Python Environment" = "~/dev/.env/bin/pip install -i https://pypi.python.org/simple -U --upgrade-strategy eager jupyter"
#"Custom command using interactive shell (unix)" = "-i vim_upgrade"
[brew]
#greedy_cask = true

View File

@@ -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};
@@ -116,6 +116,7 @@ pub enum Step {
Helix,
Krew,
Macports,
Mamba,
Mas,
Micro,
Myrepos,
@@ -336,19 +337,20 @@ pub struct ConfigFile {
vagrant: Option<Vagrant>,
flatpak: Option<Flatpak>,
distrobox: Option<Distrobox>,
no_self_update: Option<bool>,
}
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<PathBuf> {
let config_directory = config_directory(base_dirs);
fn ensure() -> Result<PathBuf> {
let config_directory = config_directory();
let config_path = config_directory.join("topgrade.toml");
@@ -372,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<PathBuf>) -> Result<ConfigFile> {
fn read(config_path: Option<PathBuf>) -> Result<ConfigFile> {
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| {
@@ -410,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);
@@ -522,6 +524,10 @@ pub struct CommandLineArgs {
/// Print roff manpage and exit
#[clap(long, hide = true)]
pub gen_manpage: bool,
/// Don't update Topgrade
#[clap(long = "no-self-update")]
pub no_self_update: bool,
}
impl CommandLineArgs {
@@ -561,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<Self> {
let config_directory = config_directory(base_dirs);
pub fn load(opt: CommandLineArgs) -> Result<Self> {
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);
@@ -591,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.
@@ -645,6 +651,11 @@ impl Config {
enabled_steps
}
/// Tell whether we should run a self update.
pub fn no_self_update(&self) -> bool {
self.opt.no_self_update || self.config_file.no_self_update.unwrap_or(false)
}
/// Tell whether we should run in tmux.
pub fn run_in_tmux(&self) -> bool {
self.opt.run_in_tmux || self.config_file.run_in_tmux.unwrap_or(false)
@@ -986,7 +997,7 @@ impl Config {
.linux
.as_ref()
.and_then(|linux| linux.rpm_ostree)
.unwrap_or(true)
.unwrap_or(false)
}
/// Should we ignore failures for this step

View File

@@ -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<Sudo>,
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<Sudo>,
git: &'a Git,
config: &'a Config,
base_dirs: &'a BaseDirs,
) -> Self {
pub fn new(run_type: RunType, sudo: Option<Sudo>, 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);
}

View File

@@ -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<PathBuf> = Lazy::new(|| home::home_dir().expect("No home directory"));
pub static XDG_DIRS: Lazy<Xdg> = Lazy::new(|| Xdg::new().expect("No home directory"));
#[cfg(windows)]
pub static WINDOWS_DIRS: Lazy<Windows> = 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());
@@ -88,7 +96,7 @@ fn run() -> Result<()> {
#[cfg(target_os = "linux")]
{
if config.display_preamble() && !config.skip_notify() {
if config.display_preamble() && terminal::supports_notify_send() && !config.skip_notify() {
print_warning("Due to a design issue with notify-send it could be that topgrade hangs when it's finished.
If this is the case on your system add the --skip-notify flag to the topgrade command or set skip_notify = true in the config file.
If you don't want this message to appear any longer set display_preamble = false in the config file.
@@ -110,13 +118,15 @@ 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);
#[cfg(feature = "self-update")]
{
if !run_type.dry() && env::var("TOPGRADE_NO_SELF_UPGRADE").is_err() {
let config_self_upgrade = env::var("TOPGRADE_NO_SELF_UPGRADE").is_err() && !config.no_self_update();
if !run_type.dry() && config_self_upgrade {
let result = self_update::self_update();
if let Err(e) = &result {
@@ -247,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() {
@@ -255,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);
@@ -317,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))?;
}
@@ -353,8 +361,8 @@ 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(&base_dirs, run_type))?;
runner.execute(Step::Juliaup, "juliaup", || generic::run_juliaup(&base_dirs, run_type))?;
runner.execute(Step::Rustup, "rustup", || generic::run_rustup(&ctx))?;
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))?;
@@ -366,23 +374,20 @@ For more information about this issue see https://askubuntu.com/questions/110969
runner.execute(Step::Vcpkg, "vcpkg", || generic::run_vcpkg_update(&ctx))?;
runner.execute(Step::Pipx, "pipx", || generic::run_pipx_update(run_type))?;
runner.execute(Step::Conda, "conda", || generic::run_conda_update(&ctx))?;
runner.execute(Step::Mamba, "mamba", || generic::run_mamba_update(&ctx))?;
runner.execute(Step::Pip3, "pip3", || generic::run_pip3_update(run_type))?;
runner.execute(Step::PipReview, "pip-review", || generic::run_pip_review_update(&ctx))?;
runner.execute(Step::Pipupgrade, "pipupgrade", || generic::run_pipupgrade_update(&ctx))?;
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))?;
@@ -393,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))?;

View File

@@ -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<PathBuf> {
fn directory_path() -> Option<PathBuf> {
#[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 }
}

View File

@@ -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};
@@ -17,6 +16,8 @@ use crate::execution_context::ExecutionContext;
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,
@@ -25,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(
@@ -83,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");
@@ -101,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");
@@ -206,24 +207,19 @@ pub fn run_apm(run_type: RunType) -> Result<()> {
.status_checked()
}
pub fn run_rustup(base_dirs: &BaseDirs, run_type: RunType) -> Result<()> {
pub fn run_rustup(ctx: &ExecutionContext) -> Result<()> {
let rustup = utils::require("rustup")?;
print_separator("rustup");
if rustup.canonicalize()?.is_descendant_of(base_dirs.home_dir()) {
run_type.execute(&rustup).args(["self", "update"]).status_checked()?;
}
run_type.execute(&rustup).arg("update").status_checked()
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()?;
}
@@ -337,10 +333,33 @@ pub fn run_conda_update(ctx: &ExecutionContext) -> Result<()> {
print_separator("Conda");
ctx.run_type()
.execute(conda)
.args(["update", "--all", "-y"])
.status_checked()
let mut command = ctx.run_type().execute(conda);
command.args(["update", "--all"]);
if ctx.config().yes(Step::Conda) {
command.arg("--yes");
}
command.status_checked()
}
pub fn run_mamba_update(ctx: &ExecutionContext) -> Result<()> {
let mamba = utils::require("mamba")?;
let output = Command::new("mamba")
.args(["config", "--show", "auto_activate_base"])
.output_checked_utf8()?;
debug!("Mamba output: {}", output.stdout);
if output.stdout.contains("False") {
return Err(SkipStep("auto_activate_base is set to False".to_string()).into());
}
print_separator("Mamba");
let mut command = ctx.run_type().execute(mamba);
command.args(["update", "--all"]);
if ctx.config().yes(Step::Mamba) {
command.arg("--yes");
}
command.status_checked()
}
pub fn run_pip3_update(run_type: RunType) -> Result<()> {
@@ -474,38 +493,46 @@ 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()
}
pub fn run_custom_command(name: &str, command: &str, ctx: &ExecutionContext) -> Result<()> {
print_separator(name);
ctx.run_type().execute(shell()).arg("-c").arg(command).status_checked()
let mut exec = ctx.run_type().execute(shell());
#[cfg(unix)]
let command = if let Some(command) = command.strip_prefix("-i ") {
exec.arg("-i");
command
} else {
command
};
exec.arg("-c").arg(command).status_checked()
}
pub fn run_composer_update(ctx: &ExecutionContext) -> Result<()> {
@@ -517,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()

View File

@@ -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());

View File

@@ -26,6 +26,7 @@ pub enum Distribution {
CentOS,
ClearLinux,
Fedora,
FedoraSilverblue,
Debian,
Gentoo,
OpenMandriva,
@@ -43,13 +44,25 @@ impl Distribution {
fn parse_os_release(os_release: &ini::Ini) -> Result<Self> {
let section = os_release.general_section();
let id = section.get("ID");
let variant: Option<Vec<&str>> = section.get("VARIANT").map(|s| s.split_whitespace().collect());
let id_like: Option<Vec<&str>> = section.get("ID_LIKE").map(|s| s.split_whitespace().collect());
Ok(match id {
Some("alpine") => Distribution::Alpine,
Some("centos") | Some("rhel") | Some("ol") => Distribution::CentOS,
Some("clear-linux-os") => Distribution::ClearLinux,
Some("fedora") | Some("nobara") => Distribution::Fedora,
Some("fedora") | Some("nobara") => {
if let Some(variant) = variant {
if variant.contains(&"Silverblue") {
return Ok(Distribution::FedoraSilverblue);
} else {
return Ok(Distribution::Fedora);
};
} else {
return Ok(Distribution::Fedora);
}
}
Some("void") => Distribution::Void,
Some("debian") | Some("pureos") => Distribution::Debian,
Some("arch") | Some("anarchy") | Some("manjaro-arm") | Some("garuda") | Some("artix") => Distribution::Arch,
@@ -103,6 +116,7 @@ impl Distribution {
Distribution::Alpine => upgrade_alpine_linux(ctx),
Distribution::Arch => archlinux::upgrade_arch_linux(ctx),
Distribution::CentOS | Distribution::Fedora => upgrade_redhat(ctx),
Distribution::FedoraSilverblue => upgrade_fedora_silverblue(ctx),
Distribution::ClearLinux => upgrade_clearlinux(ctx),
Distribution::Debian => upgrade_debian(ctx),
Distribution::Gentoo => upgrade_gentoo(ctx),
@@ -202,6 +216,14 @@ fn upgrade_redhat(ctx: &ExecutionContext) -> Result<()> {
Ok(())
}
fn upgrade_fedora_silverblue(ctx: &ExecutionContext) -> Result<()> {
let ostree = require("rpm-ostree")?;
let mut command = ctx.run_type().execute(ostree);
command.arg("upgrade");
command.status_checked()?;
Ok(())
}
fn upgrade_bedrock_strata(ctx: &ExecutionContext) -> Result<()> {
if let Some(sudo) = ctx.sudo() {
ctx.run_type().execute(sudo).args(["brl", "update"]).status_checked()?;

View File

@@ -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: <https://github.com/danhper/fundle>
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()?;

View File

@@ -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() {

View File

@@ -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");

View File

@@ -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<PathBuf> {
base_dirs
.home_dir()
pub fn vimrc() -> Result<PathBuf> {
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<PathBuf> {
fn nvimrc() -> Result<PathBuf> {
#[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");

View File

@@ -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");

View File

@@ -345,3 +345,8 @@ pub fn notify_desktop<P: AsRef<str>>(message: P, timeout: Option<Duration>) {
pub fn display_time(display_time: bool) {
TERMINAL.lock().unwrap().display_time(display_time);
}
#[cfg(target_os = "linux")]
pub fn supports_notify_send() -> bool {
TERMINAL.lock().unwrap().notify_send.is_some()
}