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},
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
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 }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -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)?;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										22
									
								
								src/main.rs
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								src/main.rs
									
									
									
									
									
								
							@ -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
									
								
							
							
						
						
									
										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