Skip to main content

para_audit/
launch.rs

1use anyhow::{Result, anyhow};
2use colored::Colorize;
3use std::{
4    path::{Path, PathBuf},
5    process::Command,
6};
7
8use crate::{get_git_path, read_yaml};
9
10pub fn open(module: &PathBuf) -> Result<()> {
11    // print module path to std for "goto"/"cd" like command
12    eprintln!(
13        "{}: {}",
14        "opening".green(),
15        module.file_name().unwrap().to_str().unwrap().italic(),
16    );
17
18    match read_yaml(module) {
19        Ok(para_yaml) => {
20            for git in para_yaml.gits {
21                if let Err(e) = init_git(&git, module) {
22                    eprintln!("{}: {}", e.to_string().red(), &git.italic());
23                }
24            }
25
26            if let Some(cmd) = para_yaml.open
27                && !cmd.is_empty()
28            {
29                // command sequence exists
30                let mut command = Command::new(cmd.first().unwrap());
31                for arg in cmd[1..].iter() {
32                    command.arg(arg);
33                }
34                command.current_dir(module);
35                if command.status().is_err() {
36                    eprintln!("{}", "failed to spawn `open` command from para.yaml".red());
37                };
38            }
39        }
40        Err(e) => {
41            eprintln!(
42                "{}",
43                format!("Error opening para.yaml: {}", e).green().italic()
44            );
45        }
46    }
47
48    let shell = std::env::var("SHELL").unwrap_or("bash".to_string());
49    Command::new(shell)
50        .current_dir(module)
51        .env("MOD", module)
52        .status()?;
53    Ok(())
54}
55
56pub fn edit_note(note: PathBuf) -> Result<()> {
57    Command::new("code")
58        .arg(note)
59        .status()
60        .or(Err(anyhow!("Couldn't start vim")))?;
61    Ok(())
62}
63
64fn init_git(git: &str, module: &Path) -> Result<()> {
65    // get git repo name (will be dir name)
66    let name = match git.split('/').next_back() {
67        Some(n) => n.trim_end_matches(".git"),
68        None => return Err(anyhow!("para.yaml git url invalid")),
69    };
70
71    // git url is defined, confirm that no dir with that name exists yet
72    if module.join(name).exists() {
73        // already exists, no problem.
74        return Ok(());
75    } else {
76        // file either doesn't exist, or is a broken symlink
77        if module.join(name).is_symlink() {
78            // must be a broken symlink, we can delete it and move on
79            std::fs::remove_file(module.join(name))?;
80        }
81    }
82
83    // check if repo in downloads, if not, get it
84    let original = get_git_path()?.join(name);
85    if !original.exists() {
86        // doesn't exist, clone it:
87        let status = Command::new("git")
88            .arg("clone")
89            .arg(git)
90            .arg(&original)
91            .status()?;
92        if !status.success() {
93            return Err(anyhow!("git clone failed"));
94        }
95    }
96    // now there is a correctly named directory in the downlaods folder,
97    // hopefully the git repo but if it's not then that's fine, whatever.
98
99    // make symbolic link here linking to cloned repo
100    std::os::unix::fs::symlink(original, module.join(name))?;
101
102    // done!
103    Ok(())
104}