~starkingdoms/starkingdoms

ref: dd101bc47e02b050cc85e160450af537e601d8fe starkingdoms/spacetime_rs/src/main.rs -rw-r--r-- 6.1 KiB
dd101bc4 — core whoa, i just rewrote spacetime again 2 years ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use std::collections::HashMap;
use std::error::Error;
use std::io::{Write};
use std::path::{PathBuf};
use std::time::SystemTime;
use tabwriter::TabWriter;
use crate::cmd::enforce_commands;
use crate::commands::api::{build_api, build_api_prod, run_api, run_api_prod};
use crate::commands::assets::build_assets;
use crate::commands::clean::{clean};
use crate::commands::client::{build_client_prod, client_protobuf, run_http};
use crate::commands::docker::{build_docker, build_docker_api, build_docker_api_beta, build_docker_api_stable, build_docker_beta, build_docker_server, build_docker_server_beta, build_docker_server_stable, build_docker_stable, build_docker_web, build_docker_web_beta, build_docker_web_stable};
use crate::commands::server::{build_server, build_server_prod, run_server, run_server_prod};

pub mod commands;
pub mod ninja;
pub mod cmd;
pub mod configure;
pub mod config;

fn main() {
    let mut bcm = BuildCommandManager::new();

    bcm.register("run_http", Box::new(run_http), "Compile the client and then run a development HTTP server", false);
    bcm.register("build_assets", Box::new(build_assets), "Compile the asset source files into spritesheets", false);
    bcm.register("client_protobuf", Box::new(client_protobuf), "Update the client protocol bindings", false);
    bcm.register("clean", Box::new(clean), "Remove all compilation artifacts", false);

    bcm.register("build_api", Box::new(build_api), "Compile the API server", false);
    bcm.register("run_api", Box::new(run_api), "Run the API server", false);
    bcm.register("build_api_prod", Box::new(build_api_prod), "Compile the API server with optimizations", false);
    bcm.register("run_api_prod", Box::new(run_api_prod), "Run the API server with optimizations", false);

    bcm.register("build_server", Box::new(build_server), "Compile the game server", false);
    bcm.register("run_server", Box::new(run_server), "Run the game server", false);
    bcm.register("build_server_prod", Box::new(build_server_prod), "Compile the game server with optimizations", false);
    bcm.register("run_server_prod", Box::new(run_server_prod), "Run the game server with optimizations", false);

    bcm.register("build_docker_beta", Box::new(build_docker_beta), "Build all three docker images for the beta channel", false);
    bcm.register("build_docker_api_beta", Box::new(build_docker_api_beta), "Build the API docker image for the beta channel", false);
    bcm.register("build_docker_server_beta", Box::new(build_docker_server_beta), "Build the main docker image for the beta channel", false);
    bcm.register("build_docker_web_beta", Box::new(build_docker_web_beta), "Build the webserver docker image for the beta channel", false);

    bcm.register("build_docker_stable", Box::new(build_docker_stable), "Build all three docker images for the stable channel", false);
    bcm.register("build_docker_api_stable", Box::new(build_docker_api_stable), "Build the API docker image for the stable channel", false);
    bcm.register("build_docker_server_stable", Box::new(build_docker_server_stable), "Build the main docker image for the stable channel", false);
    bcm.register("build_docker_web_stable", Box::new(build_docker_web_stable), "Build the webserver docker image for the stable channel", false);

    bcm.register("build_docker", Box::new(build_docker), "Build all three docker images for the bleeding channel", false);
    bcm.register("build_docker_api", Box::new(build_docker_api), "Build the API docker image for the bleeding channel", false);
    bcm.register("build_docker_server", Box::new(build_docker_server), "Build the main docker image for the bleeding channel", false);
    bcm.register("build_docker_web", Box::new(build_docker_web), "Build the webserver docker image for the bleeding channel", false);

    bcm.register("build_client_prod", Box::new(build_client_prod), "Build the production-ready client bundle", false);

    let start = SystemTime::now();

    let args: Vec<String> = std::env::args().collect();
    match bcm.exec(args) {
        Ok(_) => (),
        Err(e) => {
            let end = SystemTime::now();
            let duration = end.duration_since(start).unwrap();

            println!("[spacetime] Done in {} seconds", duration.as_secs_f32());

            eprintln!("[!] Error executing build command: {}", e);
            std::process::exit(-1);
        }
    }

    let end = SystemTime::now();
    let duration = end.duration_since(start).unwrap();

    println!("[spacetime] Done in {} seconds", duration.as_secs_f32());
}

type BuildCommandCallback = Box<dyn Fn(Vec<String>, PathBuf) -> Result<(), Box<dyn Error>>>;
#[derive(Default)]
pub struct BuildCommandManager {
    commands: HashMap<String, (BuildCommandCallback, String, bool)>
}
impl BuildCommandManager {
    pub fn new() -> Self {
        Self {
            commands: HashMap::new()
        }
    }

    pub fn register(&mut self, name: &str, command: BuildCommandCallback, description: &str, hidden: bool) {
        self.commands.insert(name.to_string(), (command, description.to_string(), hidden));
    }

    pub fn help(&self) {
        println!("Spacetime - StarKingdoms build utility");
        println!("Spacetime is a small Rust utility to assist in compiling StarKingdoms.");
        println!("Available targets:");

        let mut tw = TabWriter::new(vec![]);

        for (target, (_, description, hidden)) in &self.commands {
            if *hidden { continue };

            writeln!(tw, "\t{}\t{}", target, description).unwrap();
        }

        std::io::stdout().write_all(&tw.into_inner().unwrap()).unwrap();
    }

    pub fn exec(&self, args: Vec<String>) -> Result<(), Box<dyn Error>> {
        if args.len() < 2 || args[1] == "help" || args[1] == "h" {
            self.help();
            return Ok(())
        }

        enforce_commands();

        let main_path = PathBuf::from(args[2].to_string());

        if let Some((callback, _, _)) = self.commands.get(&args[1]) {
            callback(args[2..].to_owned(), main_path)
        } else {
            eprintln!("Unrecognized build command {}", args[1]);
            self.help();
            Ok(())
        }
    }
}