forked from lix-project/lix-installer
Rejigger the explain flag
This commit is contained in:
parent
0bcffdea80
commit
cdec8549ff
16
flake.nix
16
flake.nix
|
@ -87,6 +87,22 @@
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
|
checks = forAllSystems ({ system, pkgs, ... }:
|
||||||
|
let
|
||||||
|
pkgs = import nixpkgs {
|
||||||
|
inherit system;
|
||||||
|
};
|
||||||
|
in
|
||||||
|
{
|
||||||
|
format = pkgs.runCommand "check-format"
|
||||||
|
{
|
||||||
|
buildInputs = with pkgs; [ rustfmt cargo ];
|
||||||
|
} ''
|
||||||
|
${pkgs.nixpkgs-fmt}/bin/nixpkgs-fmt --check ${./.}
|
||||||
|
touch $out # it worked!
|
||||||
|
'';
|
||||||
|
});
|
||||||
|
|
||||||
packages = forAllSystems
|
packages = forAllSystems
|
||||||
({ system, pkgs, lib, ... }:
|
({ system, pkgs, lib, ... }:
|
||||||
let
|
let
|
||||||
|
|
|
@ -3,7 +3,7 @@ use std::path::PathBuf;
|
||||||
use bytes::Buf;
|
use bytes::Buf;
|
||||||
use reqwest::Url;
|
use reqwest::Url;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::task::{JoinError};
|
use tokio::task::JoinError;
|
||||||
|
|
||||||
use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
||||||
|
|
||||||
|
|
|
@ -69,7 +69,8 @@ impl Actionable for MoveUnpackedNix {
|
||||||
.await
|
.await
|
||||||
.map_err(|e| MoveUnpackedNixError::Rename(src_store.clone(), dest.to_owned(), e))?;
|
.map_err(|e| MoveUnpackedNixError::Rename(src_store.clone(), dest.to_owned(), e))?;
|
||||||
|
|
||||||
tokio::fs::remove_dir_all(src).await
|
tokio::fs::remove_dir_all(src)
|
||||||
|
.await
|
||||||
.map_err(|e| MoveUnpackedNixError::Rename(src_store, dest.to_owned(), e))?;
|
.map_err(|e| MoveUnpackedNixError::Rename(src_store, dest.to_owned(), e))?;
|
||||||
tracing::trace!("Moved Nix");
|
tracing::trace!("Moved Nix");
|
||||||
*action_state = ActionState::Completed;
|
*action_state = ActionState::Completed;
|
||||||
|
|
|
@ -3,7 +3,10 @@ use std::path::PathBuf;
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::task::JoinError;
|
use tokio::task::JoinError;
|
||||||
|
|
||||||
use crate::actions::base::{FetchNix, FetchNixError, MoveUnpackedNix, MoveUnpackedNixError, CreateDirectory, CreateDirectoryError};
|
use crate::actions::base::{
|
||||||
|
CreateDirectory, CreateDirectoryError, FetchNix, FetchNixError, MoveUnpackedNix,
|
||||||
|
MoveUnpackedNixError,
|
||||||
|
};
|
||||||
use crate::InstallSettings;
|
use crate::InstallSettings;
|
||||||
|
|
||||||
use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
use crate::actions::{Action, ActionDescription, ActionState, Actionable};
|
||||||
|
@ -23,7 +26,9 @@ pub struct ProvisionNix {
|
||||||
impl ProvisionNix {
|
impl ProvisionNix {
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub async fn plan(settings: InstallSettings) -> Result<Self, ProvisionNixError> {
|
pub async fn plan(settings: InstallSettings) -> Result<Self, ProvisionNixError> {
|
||||||
let create_nix_dir = CreateDirectory::plan("/nix", "root".into(), "root".into(), 0o0755, settings.force).await?;
|
let create_nix_dir =
|
||||||
|
CreateDirectory::plan("/nix", "root".into(), "root".into(), 0o0755, settings.force)
|
||||||
|
.await?;
|
||||||
|
|
||||||
let fetch_nix = FetchNix::plan(
|
let fetch_nix = FetchNix::plan(
|
||||||
settings.nix_package_url.clone(),
|
settings.nix_package_url.clone(),
|
||||||
|
@ -32,7 +37,8 @@ impl ProvisionNix {
|
||||||
.await?;
|
.await?;
|
||||||
let create_users_and_group = CreateUsersAndGroup::plan(settings.clone()).await?;
|
let create_users_and_group = CreateUsersAndGroup::plan(settings.clone()).await?;
|
||||||
let create_nix_tree = CreateNixTree::plan(settings.force).await?;
|
let create_nix_tree = CreateNixTree::plan(settings.force).await?;
|
||||||
let move_unpacked_nix = MoveUnpackedNix::plan(PathBuf::from("/nix/temp-install-dir")).await?;
|
let move_unpacked_nix =
|
||||||
|
MoveUnpackedNix::plan(PathBuf::from("/nix/temp-install-dir")).await?;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
create_nix_dir,
|
create_nix_dir,
|
||||||
fetch_nix,
|
fetch_nix,
|
||||||
|
|
|
@ -15,7 +15,7 @@ pub(crate) trait CommandExecute {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// An opinionated, experimental Nix installer
|
/// An opinionated, experimental Nix installer
|
||||||
///
|
///
|
||||||
/// Plans a Nix install, prompts for confirmation, then executes it
|
/// Plans a Nix install, prompts for confirmation, then executes it
|
||||||
#[derive(Debug, Parser)]
|
#[derive(Debug, Parser)]
|
||||||
#[clap(version)]
|
#[clap(version)]
|
||||||
|
@ -87,7 +87,6 @@ impl CommandExecute for HarmonicCli {
|
||||||
let mut settings = InstallSettings::default();
|
let mut settings = InstallSettings::default();
|
||||||
|
|
||||||
settings.force(force);
|
settings.force(force);
|
||||||
settings.explain(explain);
|
|
||||||
settings.daemon_user_count(daemon_user_count);
|
settings.daemon_user_count(daemon_user_count);
|
||||||
settings.channels(
|
settings.channels(
|
||||||
channel
|
channel
|
||||||
|
@ -99,13 +98,13 @@ impl CommandExecute for HarmonicCli {
|
||||||
let mut plan = InstallPlan::new(settings).await?;
|
let mut plan = InstallPlan::new(settings).await?;
|
||||||
|
|
||||||
// TODO(@Hoverbear): Make this smarter
|
// TODO(@Hoverbear): Make this smarter
|
||||||
if !interaction::confirm(plan.describe_execute()).await? {
|
if !interaction::confirm(plan.describe_execute(explain)).await? {
|
||||||
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!").await;
|
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!").await;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(err) = plan.install().await {
|
if let Err(err) = plan.install().await {
|
||||||
tracing::error!("{:?}", eyre!(err));
|
tracing::error!("{:?}", eyre!(err));
|
||||||
if !interaction::confirm(plan.describe_revert()).await? {
|
if !interaction::confirm(plan.describe_revert(explain)).await? {
|
||||||
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!")
|
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!")
|
||||||
.await;
|
.await;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,13 @@ pub(crate) struct Execute {
|
||||||
global = true
|
global = true
|
||||||
)]
|
)]
|
||||||
no_confirm: bool,
|
no_confirm: bool,
|
||||||
|
#[clap(
|
||||||
|
long,
|
||||||
|
action(ArgAction::SetTrue),
|
||||||
|
default_value = "false",
|
||||||
|
global = true
|
||||||
|
)]
|
||||||
|
pub(crate) explain: bool,
|
||||||
#[clap(default_value = "/dev/stdin")]
|
#[clap(default_value = "/dev/stdin")]
|
||||||
plan: PathBuf,
|
plan: PathBuf,
|
||||||
}
|
}
|
||||||
|
@ -24,7 +31,11 @@ pub(crate) struct Execute {
|
||||||
impl CommandExecute for Execute {
|
impl CommandExecute for Execute {
|
||||||
#[tracing::instrument(skip_all, fields())]
|
#[tracing::instrument(skip_all, fields())]
|
||||||
async fn execute(self) -> eyre::Result<ExitCode> {
|
async fn execute(self) -> eyre::Result<ExitCode> {
|
||||||
let Self { no_confirm, plan } = self;
|
let Self {
|
||||||
|
no_confirm,
|
||||||
|
plan,
|
||||||
|
explain,
|
||||||
|
} = self;
|
||||||
|
|
||||||
let install_plan_string = tokio::fs::read_to_string(plan)
|
let install_plan_string = tokio::fs::read_to_string(plan)
|
||||||
.await
|
.await
|
||||||
|
@ -32,14 +43,14 @@ impl CommandExecute for Execute {
|
||||||
let mut plan: InstallPlan = serde_json::from_str(&install_plan_string)?;
|
let mut plan: InstallPlan = serde_json::from_str(&install_plan_string)?;
|
||||||
|
|
||||||
if !no_confirm {
|
if !no_confirm {
|
||||||
if !interaction::confirm(plan.describe_execute()).await? {
|
if !interaction::confirm(plan.describe_execute(explain)).await? {
|
||||||
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!").await;
|
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!").await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Err(err) = plan.install().await {
|
if let Err(err) = plan.install().await {
|
||||||
tracing::error!("{:?}", eyre!(err));
|
tracing::error!("{:?}", eyre!(err));
|
||||||
if !interaction::confirm(plan.describe_revert()).await? {
|
if !interaction::confirm(plan.describe_revert(explain)).await? {
|
||||||
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!").await;
|
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!").await;
|
||||||
}
|
}
|
||||||
plan.revert().await?
|
plan.revert().await?
|
||||||
|
|
|
@ -36,13 +36,6 @@ pub(crate) struct Plan {
|
||||||
default_value = "false",
|
default_value = "false",
|
||||||
global = true
|
global = true
|
||||||
)]
|
)]
|
||||||
pub(crate) explain: bool,
|
|
||||||
#[clap(
|
|
||||||
long,
|
|
||||||
action(ArgAction::SetTrue),
|
|
||||||
default_value = "false",
|
|
||||||
global = true
|
|
||||||
)]
|
|
||||||
pub(crate) force: bool,
|
pub(crate) force: bool,
|
||||||
#[clap(default_value = "/dev/stdout")]
|
#[clap(default_value = "/dev/stdout")]
|
||||||
plan: PathBuf,
|
plan: PathBuf,
|
||||||
|
@ -60,7 +53,6 @@ impl CommandExecute for Plan {
|
||||||
channel,
|
channel,
|
||||||
no_modify_profile,
|
no_modify_profile,
|
||||||
daemon_user_count,
|
daemon_user_count,
|
||||||
explain,
|
|
||||||
force,
|
force,
|
||||||
plan,
|
plan,
|
||||||
} = self;
|
} = self;
|
||||||
|
@ -68,7 +60,6 @@ impl CommandExecute for Plan {
|
||||||
let mut settings = InstallSettings::default();
|
let mut settings = InstallSettings::default();
|
||||||
|
|
||||||
settings.force(force);
|
settings.force(force);
|
||||||
settings.explain(explain);
|
|
||||||
settings.daemon_user_count(daemon_user_count);
|
settings.daemon_user_count(daemon_user_count);
|
||||||
settings.channels(
|
settings.channels(
|
||||||
channel
|
channel
|
||||||
|
|
|
@ -16,6 +16,13 @@ pub(crate) struct Uninstall {
|
||||||
global = true
|
global = true
|
||||||
)]
|
)]
|
||||||
no_confirm: bool,
|
no_confirm: bool,
|
||||||
|
#[clap(
|
||||||
|
long,
|
||||||
|
action(ArgAction::SetTrue),
|
||||||
|
default_value = "false",
|
||||||
|
global = true
|
||||||
|
)]
|
||||||
|
pub(crate) explain: bool,
|
||||||
#[clap(default_value = "/nix/receipt.json")]
|
#[clap(default_value = "/nix/receipt.json")]
|
||||||
receipt: PathBuf,
|
receipt: PathBuf,
|
||||||
}
|
}
|
||||||
|
@ -27,6 +34,7 @@ impl CommandExecute for Uninstall {
|
||||||
let Self {
|
let Self {
|
||||||
no_confirm,
|
no_confirm,
|
||||||
receipt,
|
receipt,
|
||||||
|
explain,
|
||||||
} = self;
|
} = self;
|
||||||
|
|
||||||
let install_receipt_string = tokio::fs::read_to_string(receipt)
|
let install_receipt_string = tokio::fs::read_to_string(receipt)
|
||||||
|
@ -35,7 +43,7 @@ impl CommandExecute for Uninstall {
|
||||||
let mut plan: InstallPlan = serde_json::from_str(&install_receipt_string)?;
|
let mut plan: InstallPlan = serde_json::from_str(&install_receipt_string)?;
|
||||||
|
|
||||||
if !no_confirm {
|
if !no_confirm {
|
||||||
if !interaction::confirm(plan.describe_revert()).await? {
|
if !interaction::confirm(plan.describe_revert(explain)).await? {
|
||||||
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!").await;
|
interaction::clean_exit_with_message("Okay, didn't do anything! Bye!").await;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ impl InstallPlan {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn describe_execute(&self) -> String {
|
pub fn describe_execute(&self, explain: bool) -> String {
|
||||||
let Self {
|
let Self {
|
||||||
settings,
|
settings,
|
||||||
provision_nix,
|
provision_nix,
|
||||||
|
@ -90,7 +90,7 @@ impl InstallPlan {
|
||||||
|
|
||||||
let mut buf = String::default();
|
let mut buf = String::default();
|
||||||
buf.push_str(&format!("* {description}\n"));
|
buf.push_str(&format!("* {description}\n"));
|
||||||
if self.settings.explain {
|
if explain {
|
||||||
for line in explanation {
|
for line in explanation {
|
||||||
buf.push_str(&format!(" {line}\n"));
|
buf.push_str(&format!(" {line}\n"));
|
||||||
}
|
}
|
||||||
|
@ -130,7 +130,7 @@ impl InstallPlan {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip_all)]
|
#[tracing::instrument(skip_all)]
|
||||||
pub fn describe_revert(&self) -> String {
|
pub fn describe_revert(&self, explain: bool) -> String {
|
||||||
let Self {
|
let Self {
|
||||||
settings,
|
settings,
|
||||||
provision_nix,
|
provision_nix,
|
||||||
|
@ -168,7 +168,7 @@ impl InstallPlan {
|
||||||
|
|
||||||
let mut buf = String::default();
|
let mut buf = String::default();
|
||||||
buf.push_str(&format!("* {description}\n"));
|
buf.push_str(&format!("* {description}\n"));
|
||||||
if self.settings.explain {
|
if explain {
|
||||||
for line in explanation {
|
for line in explanation {
|
||||||
buf.push_str(&format!(" {line}\n"));
|
buf.push_str(&format!(" {line}\n"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ use url::Url;
|
||||||
|
|
||||||
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
#[derive(Debug, serde::Deserialize, serde::Serialize, Clone)]
|
||||||
pub struct InstallSettings {
|
pub struct InstallSettings {
|
||||||
pub(crate) explain: bool,
|
|
||||||
pub(crate) daemon_user_count: usize,
|
pub(crate) daemon_user_count: usize,
|
||||||
pub(crate) channels: Vec<(String, Url)>,
|
pub(crate) channels: Vec<(String, Url)>,
|
||||||
pub(crate) modify_profile: bool,
|
pub(crate) modify_profile: bool,
|
||||||
|
@ -18,7 +17,6 @@ pub struct InstallSettings {
|
||||||
impl Default for InstallSettings {
|
impl Default for InstallSettings {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
explain: Default::default(),
|
|
||||||
daemon_user_count: Default::default(),
|
daemon_user_count: Default::default(),
|
||||||
channels: Default::default(),
|
channels: Default::default(),
|
||||||
modify_profile: Default::default(),
|
modify_profile: Default::default(),
|
||||||
|
@ -38,10 +36,6 @@ impl Default for InstallSettings {
|
||||||
|
|
||||||
// Builder Pattern
|
// Builder Pattern
|
||||||
impl InstallSettings {
|
impl InstallSettings {
|
||||||
pub fn explain(&mut self, explain: bool) -> &mut Self {
|
|
||||||
self.explain = explain;
|
|
||||||
self
|
|
||||||
}
|
|
||||||
pub fn daemon_user_count(&mut self, count: usize) -> &mut Self {
|
pub fn daemon_user_count(&mut self, count: usize) -> &mut Self {
|
||||||
self.daemon_user_count = count;
|
self.daemon_user_count = count;
|
||||||
self
|
self
|
||||||
|
|
Loading…
Reference in a new issue