Rewrote how sessions are managed
This commit is contained in:
parent
c60129a190
commit
ae34531d36
|
@ -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
|
||||||
|
}
|
|
@ -3,7 +3,7 @@ use std::{
|
||||||
path::{Path, PathBuf},
|
path::{Path, PathBuf},
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{Session, User};
|
use crate::{fs::resolve_link, Session, User};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct PasswdUser {
|
struct PasswdUser {
|
||||||
|
@ -52,22 +52,11 @@ pub fn gather_sessions(user: &User) -> Vec<Session> {
|
||||||
true => gather_hm_sessions(&hm_profile),
|
true => gather_hm_sessions(&hm_profile),
|
||||||
false => vec![Session {
|
false => vec![Session {
|
||||||
name: String::from("Shell"),
|
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> {
|
fn gather_hm_sessions(path: &PathBuf) -> Vec<Session> {
|
||||||
let generation = resolve_link(path);
|
let generation = resolve_link(path);
|
||||||
let mut sessions = vec![gather_session_data(&generation, &generation)];
|
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 session_path = path.join("session");
|
||||||
|
|
||||||
let name = read_to_string(session_path.join("name")).unwrap();
|
let name = read_to_string(session_path.join("name")).unwrap();
|
||||||
let init = format!(
|
// let init = format!(
|
||||||
"sh -c \"{} && {} && {}\"",
|
// "sh -c \"{} && {} && {}\"",
|
||||||
path.join("activate").display(),
|
// path.join("activate").display(),
|
||||||
session_path.join("init").display(),
|
// session_path.join("init").display(),
|
||||||
reset_path.join("activate").display()
|
// reset_path.join("activate").display()
|
||||||
);
|
// );
|
||||||
|
let generation = path.to_str().unwrap().to_owned();
|
||||||
|
|
||||||
Session { name, init }
|
Session { name, generation }
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,8 +30,11 @@ pub fn login(
|
||||||
return Ok(LoginResult::Success);
|
return Ok(LoginResult::Success);
|
||||||
} else {
|
} else {
|
||||||
starting = true;
|
starting = true;
|
||||||
let cmd = vec![session.init.clone()];
|
let cmd = vec![String::from("nixgreety session")];
|
||||||
let env = vec![];
|
let env = vec![format!(
|
||||||
|
"NIXGREETY_GENERATION={}",
|
||||||
|
session.generation.clone()
|
||||||
|
)];
|
||||||
Request::StartSession { cmd, env }.write_to(&mut stream)?;
|
Request::StartSession { cmd, env }.write_to(&mut stream)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
22
src/main.rs
22
src/main.rs
|
@ -2,7 +2,6 @@ use std::{
|
||||||
env,
|
env,
|
||||||
fmt::Display,
|
fmt::Display,
|
||||||
io,
|
io,
|
||||||
os::unix::net::UnixStream,
|
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
|
@ -18,10 +17,27 @@ use ratatui::{
|
||||||
};
|
};
|
||||||
use tui_rain::Rain;
|
use tui_rain::Rain;
|
||||||
|
|
||||||
|
mod fs;
|
||||||
mod gather;
|
mod gather;
|
||||||
mod greetd;
|
mod greetd;
|
||||||
|
mod session;
|
||||||
|
|
||||||
fn main() -> io::Result<()> {
|
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 mut terminal = ratatui::init();
|
||||||
let app_result = App::default().run(&mut terminal);
|
let app_result = App::default().run(&mut terminal);
|
||||||
ratatui::restore();
|
ratatui::restore();
|
||||||
|
@ -111,7 +127,7 @@ impl Display for User {
|
||||||
#[derive(PartialEq, Eq, Clone)]
|
#[derive(PartialEq, Eq, Clone)]
|
||||||
struct Session {
|
struct Session {
|
||||||
name: String,
|
name: String,
|
||||||
init: String,
|
generation: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Session {
|
impl Display for Session {
|
||||||
|
@ -329,7 +345,7 @@ impl App {
|
||||||
LoginResult::Success => {
|
LoginResult::Success => {
|
||||||
self.error = false;
|
self.error = false;
|
||||||
self.status = Status::Success;
|
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 => {
|
LoginResult::Failure => {
|
||||||
self.error = true;
|
self.error = true;
|
||||||
|
|
|
@ -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(())
|
||||||
|
}
|
Loading…
Reference in New Issue