diff --git a/README.md b/README.md index 1c8aa2b2..e4a01feb 100644 --- a/README.md +++ b/README.md @@ -22,6 +22,7 @@ package manager. Topgrade is tested on and knows the following platforms: * Red Hat based * Debian based * Gentoo + * NixOS * openSUSE * Void * DragonFly BSD @@ -32,6 +33,12 @@ package manager. Topgrade is tested on and knows the following platforms: ## Installation Arch Linux users can use the [AUR](https://aur.archlinux.org/packages/topgrade/) package. +On NixOS, use the `topgrade` package in `nixpkgs`: + +```sh +nix-env -iA topgrade +``` + macOS users can install topgrade via Homebrew. Other systems users can either use `cargo install` or use the compiled binaries from the release diff --git a/src/main.rs b/src/main.rs index 66473497..5a2b4004 100644 --- a/src/main.rs +++ b/src/main.rs @@ -204,6 +204,12 @@ fn run() -> Result<(), Error> { )?; execute(&mut report, "nix", || unix::run_nix(run_type), config.no_retry())?; + execute( + &mut report, + "home-manager", + || unix::run_home_manager(run_type), + config.no_retry(), + )?; } } diff --git a/src/steps/os/linux.rs b/src/steps/os/linux.rs index a917ff9d..210d9f45 100644 --- a/src/steps/os/linux.rs +++ b/src/steps/os/linux.rs @@ -32,6 +32,7 @@ pub enum Distribution { Void, Solus, Exherbo, + NixOS, } impl Distribution { @@ -61,6 +62,7 @@ impl Distribution { Some("solus") => Distribution::Solus, Some("gentoo") => Distribution::Gentoo, Some("exherbo") => Distribution::Exherbo, + Some("nixos") => Distribution::NixOS, _ => return Err(ErrorKind::UnknownLinuxDistribution.into()), }) } @@ -91,6 +93,7 @@ impl Distribution { Distribution::Void => upgrade_void(&sudo, run_type), Distribution::Solus => upgrade_solus(&sudo, run_type), Distribution::Exherbo => upgrade_exherbo(&sudo, cleanup, run_type), + Distribution::NixOS => upgrade_nixos(&sudo, cleanup, run_type), } } @@ -331,6 +334,26 @@ fn upgrade_exherbo(sudo: &Option, cleanup: bool, run_type: RunType) -> Ok(()) } +fn upgrade_nixos(sudo: &Option, cleanup: bool, run_type: RunType) -> Result<(), Error> { + if let Some(sudo) = &sudo { + run_type + .execute(&sudo) + .args(&["/run/current-system/sw/bin/nixos-rebuild", "switch", "--upgrade"]) + .check_run()?; + + if cleanup { + run_type + .execute(&sudo) + .args(&["/run/current-system/sw/bin/nix-collect-garbage", "-d"]) + .check_run()?; + } + } else { + print_warning("No sudo detected. Skipping system upgrade"); + } + + Ok(()) +} + pub fn run_needrestart(sudo: Option<&PathBuf>, run_type: RunType) -> Result<(), Error> { let sudo = require_option(sudo)?; let needrestart = require("needrestart")?; @@ -493,4 +516,9 @@ mod tests { fn test_exherbo() { test_template(&include_str!("os_release/exherbo"), Distribution::Exherbo); } + + #[test] + fn test_nixos() { + test_template(&include_str!("os_release/nixos"), Distribution::NixOS); + } } diff --git a/src/steps/os/os_release/nixos b/src/steps/os/os_release/nixos new file mode 100644 index 00000000..35a0a0d2 --- /dev/null +++ b/src/steps/os/os_release/nixos @@ -0,0 +1,11 @@ +NAME=NixOS +ID=nixos +VERSION="20.03pre200231.7827d3f4497 (Markhor)" +VERSION_CODENAME=markhor +VERSION_ID="20.03pre200231.7827d3f4497" +PRETTY_NAME="NixOS 20.03pre200231.7827d3f4497 (Markhor)" +LOGO="nix-snowflake" +HOME_URL="https://nixos.org/" +DOCUMENTATION_URL="https://nixos.org/nixos/manual/index.html" +SUPPORT_URL="https://nixos.org/nixos/support.html" +BUG_REPORT_URL="https://github.com/NixOS/nixpkgs/issues" diff --git a/src/steps/os/unix.rs b/src/steps/os/unix.rs index 5585e6cb..d02a9600 100644 --- a/src/steps/os/unix.rs +++ b/src/steps/os/unix.rs @@ -1,4 +1,4 @@ -use crate::error::Error; +use crate::error::{Error, ErrorKind}; use crate::executor::{CommandExt, RunType}; use crate::terminal::print_separator; use crate::utils::{require, PathExt}; @@ -52,13 +52,33 @@ pub fn run_homebrew(cleanup: bool, run_type: RunType) -> Result<(), Error> { #[must_use] pub fn run_nix(run_type: RunType) -> Result<(), Error> { let nix = require("nix")?; + let nix_channel = require("nix-channel")?; let nix_env = require("nix-env")?; - print_separator("Nix"); + + #[cfg(target_os = "linux")] + { + use super::linux::Distribution; + use log::debug; + + if let Ok(Distribution::NixOS) = Distribution::detect() { + debug!("Nix on NixOS must be upgraded via 'nixos-rebuild switch', skipping."); + return Err(ErrorKind::SkipStep.into()); + } + } + run_type.execute(&nix).arg("upgrade-nix").check_run()?; + run_type.execute(&nix_channel).arg("--update").check_run()?; run_type.execute(&nix_env).arg("--upgrade").check_run() } +pub fn run_home_manager(run_type: RunType) -> Result<(), Error> { + let home_manager = require("home-manager")?; + + print_separator("home-manager"); + run_type.execute(&home_manager).arg("switch").check_run() +} + pub fn run_pearl(run_type: RunType) -> Result<(), Error> { let pearl = require("pearl")?; print_separator("pearl");