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
129
130
131
132
133
134
135
136
137
138
139
140
141
142
use clap::{Parser, Subcommand};
use standard_knowledge::StandardsLibrary;
use std::collections::HashMap;
use std::process;
use standard_knowledge::qartod::types::{ArgumentType, ArgumentValue};
#[derive(Parser)]
pub struct QcArgs {
#[clap(subcommand)]
pub command: QcCommands,
}
#[derive(Subcommand)]
pub enum QcCommands {
/// List all QARTOD test suites
List {
/// Name of the test suite to get info about
standard_name: String,
},
/// Get info about a specific QARTOD test suite
Get {
/// Name of the test suite to get info about
standard_name: String,
/// Name of test suite
test_suite: String,
},
/// Generate a configuration for a specific QARTOD test suite
Config {
/// Name of the test suite to get info about
standard_name: String,
/// Name of test suite
test_suite: String,
/// Test configuration arguments
args: Vec<String>,
},
}
pub fn execute(qc_args: &QcArgs, library: &StandardsLibrary) {
match &qc_args.command {
QcCommands::List { standard_name } => {
if let Ok(standard) = library.get(standard_name.as_str()) {
if standard.qartod.is_empty() {
eprintln!("No QARTOD test suites for standard: {standard_name}");
process::exit(2);
} else {
println!(
"QARTOD Test Suites for {}:\n{}",
standard_name,
standard
.qartod
.iter()
.map(|suite| format!("- {}", suite.info()))
.collect::<Vec<String>>()
.join("\n")
);
}
} else {
eprintln!("Didn't find a standard matching: {standard_name}");
process::exit(2)
}
}
QcCommands::Get {
standard_name,
test_suite,
} => {
if let Ok(standard) = library.get(standard_name.as_str()) {
if let Some(suite) = standard
.qartod
.iter()
.find(|s| s.info().slug == *test_suite)
{
println!("{}", suite.info().details());
} else {
eprintln!(
"No QARTOD test suite named: {test_suite} for standard: {standard_name}"
);
process::exit(2);
}
} else {
eprintln!("Didn't find a standard matching: {standard_name}");
process::exit(2)
}
}
QcCommands::Config {
standard_name,
test_suite,
args,
} => {
if let Ok(standard) = library.get(standard_name.as_str()) {
if let Some(suite) = standard
.qartod
.iter()
.find(|s| s.info().slug == *test_suite)
{
let info = suite.info();
let mut arguments: HashMap<String, ArgumentValue> = HashMap::new();
for arg in args {
let parts: Vec<&str> = arg.split('=').collect();
if parts.len() == 2 {
let key = parts[0];
let value = parts[1];
let arg_type = info
.arguments
.get(key)
.map(|arg| arg.argument_type.clone())
.unwrap_or(ArgumentType::String);
let arg_value = arg_type.value_type(value);
arguments.insert(key.to_string(), arg_value);
} else {
eprintln!("Invalid argument format: {arg}");
process::exit(2);
}
}
let config = suite.scaffold(arguments);
if let Err(error) = config {
eprintln!("Error generating configuration: {error}");
process::exit(2);
} else {
let yaml = serde_yaml_ng::to_string(&config.unwrap())
.expect("Failed to serialize configuration to YAML");
println!("Generated configuration for {}:\n{yaml}", info.name);
}
} else {
eprintln!(
"No QARTOD test suite named: {test_suite} for standard: {standard_name}"
);
process::exit(2);
}
} else {
eprintln!("Didn't find a standard matching: {standard_name}");
process::exit(2)
}
}
}
}