Rewrote how sessions are managed
This commit is contained in:
		
							parent
							
								
									c60129a190
								
							
						
					
					
						commit
						ae34531d36
					
				
							
								
								
									
										11
									
								
								src/fs.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/fs.rs
									
									
									
									
									
										Normal 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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -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;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										56
									
								
								src/session.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										56
									
								
								src/session.rs
									
									
									
									
									
										Normal 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(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user