Skip to content

Commit

Permalink
feat(home): print summary and ask for confirmation
Browse files Browse the repository at this point in the history
  • Loading branch information
fosskers committed Nov 27, 2023
1 parent 5ec1a96 commit 33d11c6
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 36 deletions.
3 changes: 3 additions & 0 deletions rust/aura-pm/i18n/en-US/aura_pm.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ home-non-existant = These packages do not exist: { $pkgs }
home-not-a-link = File already exists and is not a symlink: { $file }
home-no-target = Symlink at { $file } points to a non-existent file.
home-wrong-target = Symlink at { $file } points to an unexpected target.
home-determine = Determining packages and symlinks...
home-to-install = Repository packages to install:
home-symlinks = Symlinks to establish:
# Runtime Environment
env-missing-editor = Provided EDITOR is not on the PATH.
Expand Down
92 changes: 59 additions & 33 deletions rust/aura-pm/src/command/home.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,11 @@
use crate::env::{Env, Home, LinkStatus};
use crate::error::Nested;
use crate::localization::Localised;
use crate::{aura, proceed};
use alpm::Alpm;
use alpm_utils::DbListExt;
use colored::*;
use i18n_embed::fluent::FluentLanguageLoader;
use i18n_embed_fl::fl;
use nonempty_collections::NEVec;
use std::ops::Not;
Expand All @@ -25,6 +28,7 @@ pub(crate) enum Error {
NotALink(PathBuf),
NoTarget(PathBuf),
WrongTarget(PathBuf),
Cancelled,
}

impl Nested for Error {
Expand All @@ -49,6 +53,7 @@ impl Localised for Error {
Error::WrongTarget(p) => {
fl!(fll, "home-wrong-target", file = format!("{}", p.display()))
}
Error::Cancelled => fl!(fll, "common-cancelled"),
}
}
}
Expand All @@ -61,43 +66,64 @@ pub(crate) fn links_established(home: &Home, xdg_config: &Path) -> bool {
}

/// Install all missing, expected packages, and establish any specified symlinks.
pub(crate) fn apply(env: &Env, alpm: &Alpm) -> Result<(), Error> {
match env.home.as_ref() {
None => Err(Error::NoHome),
Some(home) => {
let packages = pkgs_to_install(home, alpm)
.ok()
.map_err(Error::NonExistant)?;

let config = env.xdg_config.as_path();

println!("Packages to install:");
for p in packages {
println!("{p}");
}
pub(crate) fn apply(fll: &FluentLanguageLoader, env: &Env, alpm: &Alpm) -> Result<(), Error> {
let home = env.home.as_ref().ok_or(Error::NoHome)?;

let to_establish = home
.links
.iter()
.filter_map(|sl| match sl.status(config) {
LinkStatus::NotALink => Some(Err(Error::NotALink(sl.pretty(config)))),
LinkStatus::NoTarget => Some(Err(Error::NoTarget(sl.pretty(config)))),
LinkStatus::WrongTarget => Some(Err(Error::WrongTarget(sl.pretty(config)))),
// A symlink is ready to be made.
LinkStatus::NothingThere => Some(Ok(sl)),
// We can safely ignore established, correct symlinks.
LinkStatus::Established => None,
})
.collect::<Result<Vec<_>, _>>()?;

if to_establish.is_empty().not() {
println!("Links to establish:");
println!("{:?}", to_establish);
}
aura!(fll, "home-determine");

let packages = pkgs_to_install(home, alpm)
.ok()
.map_err(Error::NonExistant)?;

if packages.is_empty().not() {
aura!(fll, "home-to-install");

for p in packages.iter() {
println!(" {p}");
}
}

let config = env.xdg_config.as_path();

Ok(())
let to_establish = home
.links
.iter()
.filter_map(|sl| match sl.status(config) {
LinkStatus::NotALink => Some(Err(Error::NotALink(sl.absolute(config)))),
LinkStatus::NoTarget => Some(Err(Error::NoTarget(sl.absolute(config)))),
LinkStatus::WrongTarget => Some(Err(Error::WrongTarget(sl.absolute(config)))),
// A symlink is ready to be made.
LinkStatus::NothingThere => Some(Ok(sl)),
// We can safely ignore established, correct symlinks.
LinkStatus::Established => None,
})
.collect::<Result<Vec<_>, _>>()?;

if to_establish.is_empty().not() {
aura!(fll, "home-symlinks");

// To align the rendering of the symlinks.
let longest = to_establish
.iter()
.map(|sl| sl.str_of_from().chars().count())
.max()
.unwrap_or(0);

for sl in to_establish.iter() {
println!(
" {:w$} -> {}",
sl.from().display(),
sl.to().display(),
w = longest
);
}
}

if packages.is_empty().not() || to_establish.is_empty().not() {
proceed!(fll, "proceed").ok_or(Error::Cancelled)?;
}

Ok(())
}

fn pkgs_to_install<'a>(home: &'a Home, alpm: &Alpm) -> Validated<Vec<&'a str>, String> {
Expand Down
8 changes: 6 additions & 2 deletions rust/aura-pm/src/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -378,8 +378,12 @@ impl Symlink {
Path::new(self.0 .0.as_str())
}

pub(crate) fn str_of_from(&self) -> &str {
self.0 .0.as_str()
}

/// An absolute rendering of the path of the symlink.
pub(crate) fn pretty(&self, xdg_config: &Path) -> PathBuf {
pub(crate) fn absolute(&self, xdg_config: &Path) -> PathBuf {
xdg_config.join(self.from())
}

Expand All @@ -390,7 +394,7 @@ impl Symlink {
/// the system. In that case, the `home` command should be halted and the
/// user warned.
pub(crate) fn status(&self, xdg_config: &Path) -> LinkStatus {
let path = self.pretty(xdg_config);
let path = self.absolute(xdg_config);

match path {
p if p.exists().not() => LinkStatus::NothingThere,
Expand Down
2 changes: 1 addition & 1 deletion rust/aura-pm/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,7 +177,7 @@ fn work(args: Args, fll: &FluentLanguageLoader) -> Result<(), Error> {
// --- System Validation --- //
SubCmd::Check(_) => check::check(fll, &env)?,
// --- Consistent System --- //
SubCmd::Home(_) => home::apply(&env, &env.alpm()?)?,
SubCmd::Home(_) => home::apply(fll, &env, &env.alpm()?)?,
}

Ok(())
Expand Down

0 comments on commit 33d11c6

Please sign in to comment.