1
use clap::{Parser, Subcommand, ValueEnum};
2

            
3
use crate::project_model;
4

            
5
/// [`CliArgs`] is the command line arguments parser
6
///
7
/// #Test
8
/// ```rust
9
/// use clap::Parser;
10
/// use zork::cli::input::{CliArgs, Command, CppCompiler,TemplateValues};
11
///
12
/// let parser = CliArgs::parse_from(
13
///     ["", "-vv", "--match-files", "zork_linux.toml", "--root", ".", "--clear-cache", "--driver-path", "/usr/bin/clang-15/clang++", "--targets", "executable,tests", "test"]
14
/// );
15
/// assert_eq!(parser.command, Command::Test);
16
/// assert_eq!(parser.verbose, 2);
17
/// assert_eq!(parser.root, Some(String::from(".")));
18
/// assert_eq!(parser.clear_cache, true);
19
/// assert_eq!(parser.driver_path, Some(String::from("/usr/bin/clang-15/clang++")));
20
/// assert_eq!(parser.targets, Some(vec![String::from("executable"), String::from("tests")]));
21
///
22
// Create Template Project
23
/// let parser = CliArgs::parse_from(["", "new", "example", "--git", "--compiler", "clang"]);
24
/// assert_eq!(parser.command, Command::New{name: "example".to_owned(), git: true, compiler: CppCompiler::CLANG, template: TemplateValues::PARTITIONS});
25
///
26
// Run autogenerated project
27
// let parser = CliArgs::parse_from(["", "-vv", "run"]);
28
// assert_eq!(parser.command, Command::Run);
29
/// ```
30
172
#[derive(Parser, Debug, Default)]
31
#[command(name = "Zork++")]
32
#[command(author = "Zero Day Code")]
33
#[command(version = "0.11.2")]
34
#[command(
35
    about = "Zork++ is a build system for modern C++ projects",
36
    long_about = "Zork++ is a project of Zero Day Code. Find us: https://github.com/zerodaycode/Zork"
37
)]
38
pub struct CliArgs {
39
11
    #[command(subcommand)]
40
    pub command: Command,
41

            
42
22
    #[arg(short, long, action = clap::ArgAction::Count, help = "Zork++ maximum allowed verbosity level is: '-vv'")]
43
    pub verbose: u8,
44

            
45
22
    #[arg(short, long, help = "Removes all the entries stored in the cache")]
46
    pub clear_cache: bool,
47

            
48
22
    #[arg(short, long, help = "Allows the user to specify the project's root")]
49
    pub root: Option<String>,
50

            
51
22
    #[arg(
52
        short,
53
        long,
54
        help = "The name of the targets that Zork++ must take in consideration for the current invokation",
55
        value_delimiter(',')
56
    )]
57
15
    pub targets: Option<Vec<String>>,
58

            
59
22
    #[arg(
60
        short,
61
        long,
62
        help = "Allows the user to specify the compilers frontend path"
63
    )]
64
    pub driver_path: Option<String>,
65

            
66
22
    #[arg(
67
        short,
68
        long,
69
        help = "Filters between the Zork++ configuration files for the project, taking only the ones that contains in their name the value passed in"
70
    )]
71
    pub match_files: Option<String>,
72
}
73

            
74
/// [`Command`] -  The core enum commands
75
121
#[derive(Subcommand, Debug, PartialEq, Eq, Default)]
76
pub enum Command {
77
    /// Triggers the process that builds the project based on the config file directives
78
    #[default]
79
    Build,
80
    /// Builds and runs the targetted project
81
    Run,
82
    /// Executes the tests under the specified directory in the config file
83
    Test,
84
    /// Creates a new template project
85
    New {
86
22
        #[arg(help = "Name of the new project")]
87
        name: String,
88
22
        #[arg(long, help = "Initialize a new local git repo")]
89
        git: bool,
90
22
        #[arg(long, default_value = "clang", help = "Which compiler to use")]
91
        compiler: CppCompiler,
92
22
        #[arg(
93
            long,
94
            default_value = "partitions",
95
            help = "What configuration file template to use"
96
        )]
97
        template: TemplateValues,
98
    },
99
}
100

            
101
20
#[derive(ValueEnum, Eq, PartialEq, Debug, Clone, Copy)]
102
pub enum TemplateValues {
103
6
    BASIC,
104
4
    PARTITIONS,
105
}
106

            
107
/// [`CppCompiler`] The C++ compilers available within Zork++ as a command line argument for the `new` argument
108
24
#[derive(ValueEnum, Copy, Clone, Debug, PartialEq, Eq)]
109
pub enum CppCompiler {
110
6
    CLANG,
111
4
    MSVC,
112
4
    GCC,
113
}
114

            
115
/// Clippy warns to prefer implementing the From trait instead of Into.
116
/// That would require that the project model know about cli details, which is ugly.
117
#[allow(clippy::from_over_into)]
118
impl Into<project_model::compiler::CppCompiler> for CppCompiler {
119
2
    fn into(self) -> project_model::compiler::CppCompiler {
120
2
        match self {
121
1
            CppCompiler::CLANG => project_model::compiler::CppCompiler::CLANG,
122
            CppCompiler::MSVC => project_model::compiler::CppCompiler::MSVC,
123
1
            CppCompiler::GCC => project_model::compiler::CppCompiler::GCC,
124
        }
125
2
    }
126
}