aboutsummaryrefslogtreecommitdiff
path: root/crates/divina/src/cli.rs
blob: 2d8f58e375b10b078edefffdedd83b57e34465e6 (plain) (blame)
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
// Copyright (C) 2022-2022 Fuwn <[email protected]>
// SPDX-License-Identifier: GPL-3.0-only

use std::path::Path;

use structopt::clap::{App, AppSettings, Arg, SubCommand};

/// Create CLI
fn cli() -> App<'static, 'static> {
  App::new(env!("CARGO_PKG_NAME"))
    .about(env!("CARGO_PKG_DESCRIPTION"))
    .version(env!("CARGO_PKG_VERSION"))
    .author(env!("CARGO_PKG_AUTHORS"))
    .setting(AppSettings::SubcommandRequiredElseHelp)
    .subcommands(vec![
      SubCommand::with_name("init").about("").args(&[
        Arg::with_name("type")
          .long("type")
          .takes_value(true)
          .possible_values(&["bin", "lib"]),
        Arg::with_name("git").long("git").takes_value(true),
        Arg::with_name("path").index(1).takes_value(true),
      ]),
      SubCommand::with_name("build").about("Build your project"),
      SubCommand::with_name("clean")
        .about("Cleanup Divina's non-essential temporary files and directories"),
      SubCommand::with_name("config")
        .about("")
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommands(vec![
          SubCommand::with_name("show").about("Print your configuration"),
          SubCommand::with_name("validate").about("Check if your configuration will compile"),
          SubCommand::with_name("compiler")
            .about("Access the Divina compiler wrapper")
            .setting(AppSettings::SubcommandRequiredElseHelp)
            .subcommands(vec![
              SubCommand::with_name("show").about("Print Divina's compiler configuration")
            ]),
        ]),
    ])
    .args(&[
      Arg::with_name("debug").short("d").long("debug"),
      Arg::with_name("trace").short("t").long("trace"),
    ])
}

/// Execute CLI
pub fn execute(divina: &mut crate::Divina) {
  let matches = cli().get_matches();

  match matches.subcommand() {
    ("init", Some(init_matches)) => {
      let repository = init_matches
        .value_of("git")
        .unwrap_or("https://github.com/divinaland/init.git");
      let path = init_matches.value_of("path").unwrap_or(".");

      if Path::new("Divina.lua").exists() {
        divina_util::exit_with!(
          1,
          "!! could not clone init repository to '{}', a 'Divina.lua' already exists",
          path
        );
      }

      divina_git::clone(repository, &format!("./{}", path))
        .expect("!! could not clone init repository, perhaps the repository is invalid ?");
    }
    ("build", Some(_build_matches)) => {
      divina
        .compiler
        .find_sources(divina.expose_config())
        .compile()
        .link();
    }
    ("clean", Some(_clean_matches)) =>
      if Path::new("out/").exists() {
        println!(":: removing directory 'out/'");
        std::fs::remove_dir_all("out/")
          .expect("!! could not remove directory 'out/', check permissions");
      } else {
        println!(":: directory 'out/' does not exist");
      },
    ("config", Some(config_matches)) =>
      match config_matches.subcommand() {
        ("show", _) => divina.print_config(),
        ("validate", _) => println!(":: no issues found"),
        ("compiler", Some(config_compiler_matches)) =>
          match config_compiler_matches.subcommand() {
            ("show", _) => {
              let _ = divina
                .compiler
                .find_sources(divina.expose_config())
                .print_config();
            }
            _ => unreachable!(),
          },
        _ => unreachable!(),
      },
    _ => unreachable!(),
  }
}