Rewrote how sessions are managed

This commit is contained in:
Jan-Bulthuis 2025-02-22 01:30:17 +01:00
parent c60129a190
commit ae34531d36
5 changed files with 101 additions and 25 deletions

11
src/fs.rs Normal file
View File

@ -0,0 +1,11 @@
use std::{fs::read_link, path::PathBuf};
pub fn resolve_link(path: &PathBuf) -> PathBuf {
let mut location = path.clone();
while let Ok(next) = read_link(&location) {
let base_path = location.parent().unwrap();
let next_path = base_path.join(next);
location = next_path;
}
location
}

View File

@ -3,7 +3,7 @@ use std::{
path::{Path, PathBuf},
};
use crate::{Session, User};
use crate::{fs::resolve_link, Session, User};
#[derive(Debug)]
struct PasswdUser {
@ -52,22 +52,11 @@ pub fn gather_sessions(user: &User) -> Vec<Session> {
true => gather_hm_sessions(&hm_profile),
false => vec![Session {
name: String::from("Shell"),
init: user.shell.to_str().unwrap().to_owned(),
generation: user.shell.to_str().unwrap().to_owned(),
}],
}
}
#[allow(clippy::ptr_arg)]
fn resolve_link(path: &PathBuf) -> PathBuf {
let mut location = path.clone();
while let Ok(next) = read_link(&location) {
let base_path = location.parent().unwrap();
let next_path = base_path.join(next);
location = next_path;
}
location
}
fn gather_hm_sessions(path: &PathBuf) -> Vec<Session> {
let generation = resolve_link(path);
let mut sessions = vec![gather_session_data(&generation, &generation)];
@ -105,12 +94,13 @@ fn gather_session_data(path: &PathBuf, reset_path: &PathBuf) -> Session {
let session_path = path.join("session");
let name = read_to_string(session_path.join("name")).unwrap();
let init = format!(
"sh -c \"{} && {} && {}\"",
path.join("activate").display(),
session_path.join("init").display(),
reset_path.join("activate").display()
);
// let init = format!(
// "sh -c \"{} && {} && {}\"",
// path.join("activate").display(),
// session_path.join("init").display(),
// reset_path.join("activate").display()
// );
let generation = path.to_str().unwrap().to_owned();
Session { name, init }
Session { name, generation }
}

View File

@ -30,8 +30,11 @@ pub fn login(
return Ok(LoginResult::Success);
} else {
starting = true;
let cmd = vec![session.init.clone()];
let env = vec![];
let cmd = vec![String::from("nixgreety session")];
let env = vec![format!(
"NIXGREETY_GENERATION={}",
session.generation.clone()
)];
Request::StartSession { cmd, env }.write_to(&mut stream)?;
}
}

View File

@ -2,7 +2,6 @@ use std::{
env,
fmt::Display,
io,
os::unix::net::UnixStream,
path::PathBuf,
time::{Duration, Instant},
};
@ -18,10 +17,27 @@ use ratatui::{
};
use tui_rain::Rain;
mod fs;
mod gather;
mod greetd;
mod session;
fn main() -> io::Result<()> {
let mut args = env::args();
let _ = args.next();
let mode = args.next();
match mode {
Some(mode) => match mode.as_str() {
"greeter" => draw_app(),
"session" => session::handle_session(),
_ => panic!("Unrecognized mode: {}", mode),
},
None => draw_app(),
}
}
fn draw_app() -> io::Result<()> {
let mut terminal = ratatui::init();
let app_result = App::default().run(&mut terminal);
ratatui::restore();
@ -111,7 +127,7 @@ impl Display for User {
#[derive(PartialEq, Eq, Clone)]
struct Session {
name: String,
init: String,
generation: String,
}
impl Display for Session {
@ -329,7 +345,7 @@ impl App {
LoginResult::Success => {
self.error = false;
self.status = Status::Success;
self.exit_time = Some(Instant::now() + Duration::from_millis(300));
self.exit_time = Some(Instant::now() + Duration::from_millis(200));
}
LoginResult::Failure => {
self.error = true;

56
src/session.rs Normal file
View File

@ -0,0 +1,56 @@
use std::{
env,
fs::{read_dir, DirEntry},
io,
path::PathBuf,
process::{Command, Stdio},
};
use crate::fs::resolve_link;
pub fn handle_session() -> io::Result<()> {
println!(">>> Activating environment <<<");
let generation = env::var("NIXGREETY_GENERATION").unwrap();
Command::new(format!("{}/activate", generation))
.stdout(Stdio::inherit())
.output()
.expect("Failed to activate environment");
println!(">>> Creating session <<<");
Command::new(format!("{}/session/init", generation))
.stdout(Stdio::inherit())
.output()
.expect("Failed to create session");
println!(">>> Deactivating environment <<<");
let home = env::var("HOME").unwrap();
let profile_path = PathBuf::from(format!("{}/.local/state/nix/profiles/", home));
let mut generations: Vec<DirEntry> = read_dir(profile_path)
.expect("Failed to gather home-manager generations")
.flatten()
.collect();
generations.sort_by_key(|entry| entry.file_name());
let generation = generations
.into_iter()
.rev()
.filter(|entry| {
entry
.file_name()
.to_string_lossy()
.starts_with("home-manager-")
})
.find(|entry| {
let entry_path = entry.path();
let resolved_path = resolve_link(&entry_path);
let specialisation_path = resolved_path.join("specialisation");
specialisation_path.exists()
})
.map(|entry| entry.path())
.unwrap_or(PathBuf::from(""));
Command::new(format!("{}/activate", generation.display()))
.stdout(Stdio::inherit())
.output()
.unwrap();
Ok(())
}