oseda_cli/cmd/
init.rs

1/*
2npm init -y
3npm install --save-dev vite http-server
4npm install reveal.js serve vite-plugin-singlefile
5touch vite.config.js -> add the plugin, write this by hand
6
7*/
8
9use std::{
10    error::Error,
11    fs::{self, File},
12    io::{self, BufWriter, Write, stdin},
13    panic::PanicHookInfo,
14    path::{Path, PathBuf},
15    process::Command,
16};
17
18use chrono::{DateTime, Utc};
19use clap::Args;
20use serde::{Deserialize, Serialize};
21use strum::IntoEnumIterator;
22
23use crate::{
24    categories::{self, Category},
25    config, github,
26};
27
28#[derive(Args, Debug)]
29pub struct InitOptions {
30    #[arg(long, required = false)]
31    presentation_only: bool,
32}
33
34const PACKAGE_JSON: &str = include_str!("../static/package.json");
35const VITE_CONFIG_JS: &str = include_str!("../static/vite.config.js");
36const INDEX_HTML: &str = include_str!("../static/index.html");
37const MAIN_JS: &str = include_str!("../static/main.js");
38const SLIDES_MD: &str = include_str!("../static/slides.md");
39const CUSTOM_CSS: &str = include_str!("../static/custom.css");
40
41pub fn init(opts: InitOptions) -> Result<(), Box<dyn Error>> {
42    // path/[conf.title]
43
44    let conf = config::create_conf()?;
45
46    // println!("opts path {:?}", &opts.path);
47    std::fs::create_dir_all(&conf.title)?;
48    // Command::new("cd").arg(&opts.path).spawn()?;
49
50    let output = Command::new("npm")
51        .args(["init", "-y", "--prefix", &conf.title])
52        .current_dir(&conf.title)
53        .output()?;
54
55    // swapped to explicit check so it doesnt hang after
56    if !output.status.success() {
57        eprintln!(
58            "npm init failed: {}",
59            String::from_utf8_lossy(&output.stderr)
60        );
61        return Err("npm init failed".into());
62    }
63
64    let npm_commands = vec![
65        format!("install --save-dev vite http-server"),
66        format!("install reveal.js serve vite-plugin-singlefile"),
67    ];
68
69    for c in npm_commands {
70        let args: Vec<&str> = c.split(' ').collect();
71        let output = Command::new("npm")
72            .args(&args)
73            .current_dir(&conf.title)
74            .output()?;
75
76        if !output.status.success() {
77            eprintln!(
78                "npm {} failed: {}",
79                c,
80                String::from_utf8_lossy(&output.stderr)
81            );
82            return Err(format!("npm {} failed", c).into());
83        }
84        println!("Bootstrapped npm {}", c);
85
86        println!("Saving config file...");
87
88        config::write_config(&conf.title, &conf)?;
89    }
90
91    fs::write(format!("{}/package.json", &conf.title), PACKAGE_JSON)?;
92    fs::write(format!("{}/vite.config.js", &conf.title), VITE_CONFIG_JS)?;
93    fs::write(format!("{}/index.html", &conf.title), INDEX_HTML)?;
94
95    std::fs::create_dir_all(format!("{}/src", &conf.title))?;
96    fs::write(format!("{}/src/main.js", &conf.title), MAIN_JS)?;
97
98    std::fs::create_dir_all(format!("{}/slides", &conf.title))?;
99    fs::write(format!("{}/slides/slides.md", &conf.title), SLIDES_MD)?;
100
101    std::fs::create_dir_all(format!("{}/css", &conf.title))?;
102    fs::write(format!("{}/css/custom.css", &conf.title), CUSTOM_CSS)?;
103
104    Ok(())
105}