acorn_lib/util/cli.rs
1//! # Command line interface (CLI) utilities
2//!
3//! Common utilities and structs used to create a command line interface using ACORN schemas
4use crate::util::{files_all, files_from_git_branch, files_from_git_commit, git_branch_name};
5use bon::Builder;
6use clap::ValueEnum;
7use derive_more::Display;
8use serde::Serialize;
9use std::path::PathBuf;
10
11/// Catagories available when analyzing ("checking") research activity data
12///
13/// Used primarily by ACORN CLI
14#[derive(Clone, Debug, Display, PartialEq, ValueEnum, Serialize)]
15#[serde(rename_all = "lowercase")]
16pub enum Check {
17 /// Static analysis of prose
18 #[display("analysis")]
19 Analysis,
20 /// Folder structure and file naming
21 #[display("conventions")]
22 Conventions,
23 /// Readability of prose
24 #[display("readability")]
25 Readability,
26 /// Schema validation via Rust type system
27 #[display("validation")]
28 Validation,
29}
30/// Catagories available when performing system diagnostics before using ACORN
31///
32/// Used primarily by ACORN CLI
33#[derive(Clone, Copy, Debug, Default, Display, PartialEq, ValueEnum, Serialize)]
34#[serde(rename_all = "lowercase")]
35pub enum Diagnostic {
36 /// All available diagnostics
37 #[default]
38 #[display("all")]
39 All,
40 /// System information (e.g. CPU count, OS, etc...)
41 #[display("system")]
42 System,
43 /// Memory information and usage
44 #[display("memory")]
45 Memory,
46 /// Network information
47 #[display("network")]
48 Network,
49 /// Graphics Processing Unit (GPU) information
50 #[display("gpu")]
51 Gpu,
52 /// Check for installed software
53 #[display("software")]
54 Software,
55}
56/// Target export file formats available when exporting research activity data using acorn
57///
58/// Used primarily by ACORN CLI
59#[derive(Clone, Debug, Default, Display, ValueEnum, Serialize)]
60pub enum FileFormat {
61 /// Portable Document Format
62 #[default]
63 #[display("pdf")]
64 Pdf,
65 /// Microsoft PowerPoint
66 ///
67 /// Only available for certain targets (e.g. highlights)
68 #[display("powerpoint")]
69 Powerpoint,
70}
71/// Target artifact aspect ratio size available when exporting research activity data using acorn
72///
73/// Used primarily by ACORN CLI
74#[derive(Clone, Debug, Default, Display, ValueEnum, Serialize)]
75#[serde(rename_all = "lowercase")]
76pub enum Size {
77 /// Standard size (4:3)
78 #[display("standard")]
79 Standard,
80 /// Widescreen size (16:9)
81 #[default]
82 #[display("widescreen")]
83 Widescreen,
84}
85/// Target artifact types available when exporting research activity data using acorn
86///
87/// Used primarily by ACORN CLI
88#[derive(Clone, Copy, Debug, Default, Display, ValueEnum, Serialize)]
89#[serde(rename_all = "lowercase")]
90pub enum Target {
91 /// US letter sized single page PDF document presenting a certain research activity data
92 #[default]
93 #[display("fact-sheet")]
94 FactSheet,
95 /// Single slide PowerPoint presentation for a certain research activity data
96 #[display("highlight")]
97 Highlight,
98 /// Poster sized presentation format intended for large printing and presentation
99 #[display("poster")]
100 Poster,
101}
102/// Target artifact branding available when exporting research activity data using acorn
103///
104/// Used primarily by ACORN CLI
105#[derive(Default, Clone, Copy, Debug, Display)]
106pub enum TargetLabel {
107 /// National Security Sciences Directorate
108 ///
109 /// See <https://www.ornl.gov/science-area/national-security>
110 #[default]
111 #[display("National Security Sciences")]
112 Nssd,
113 /// Biological and Environmental Systems Sciences Directorate
114 ///
115 /// See <https://www.ornl.gov/directorate/bessd>
116 #[display("Biological and Environmental Systems Sciences")]
117 Bessd,
118 /// ORNL Water Power Program
119 ///
120 /// See <https://www.ornl.gov/waterpower>
121 #[display("Water Power Program")]
122 Wpp,
123 /// General ORNL Branding
124 #[display("Solving Big Problems")]
125 Ornl,
126}
127/// Container struct for working with ACORN CLI subcommand run functions
128#[derive(Builder, Clone, Debug, Default)]
129#[builder(start_fn = init)]
130pub struct Options {
131 /// Path to file or folder to be used for input
132 pub path: Option<PathBuf>,
133 /// Git branch name
134 pub branch: Option<String>,
135 /// Git commit hash
136 pub commit: Option<String>,
137 /// Regex pattern of files to ignore at a given path desginated by `path`
138 pub ignore: Option<String>,
139 /// Path to file or folder to be used for output
140 pub output: Option<PathBuf>,
141 /// Path to reference file
142 ///
143 /// e.g. reference.pptx for exporting RAD to PowerPoint
144 pub reference: Option<PathBuf>,
145 /// Artifact aspect ratio size
146 pub size: Option<Size>,
147 /// Artifact target type
148 pub target: Option<Target>,
149 /// Flag used to indicate if a single error should cause the process to exit
150 #[builder(default)]
151 pub exit_on_first_error: bool,
152 /// Flag used to indicate if changed files should be obtained from a merge request
153 #[builder(default)]
154 pub merge_request: bool,
155}
156impl TargetLabel {
157 /// Returns a string representing the folder name for the given TargetLabel
158 pub fn folder(self) -> String {
159 match self {
160 | TargetLabel::Bessd => "bessd".to_string(),
161 | TargetLabel::Wpp => "wpp".to_string(),
162 | TargetLabel::Nssd => "nssd".to_string(),
163 | TargetLabel::Ornl => TargetLabel::default().folder().to_owned(),
164 }
165 }
166 /// Returns a TargetLabel based on the given organization name
167 pub fn from_organization(name: &str) -> Self {
168 match name {
169 | "Biological and Environmental Systems Science Directorate" => TargetLabel::Bessd,
170 | "National Security Sciences Division" => TargetLabel::Nssd,
171 | "Oak Ridge National Laboratory" => TargetLabel::Ornl,
172 | "Water Power Program" => TargetLabel::Wpp,
173 | _ => TargetLabel::default(),
174 }
175 }
176}
177/// Returns a vector of PathBuf from the given options
178///
179/// If the options specify a merge request, the files from the current branch are returned.
180/// If the options specify a commit, the files changed in the commit are returned.
181/// If the options specify a branch, the files changed in the branch are returned.
182/// If none of the above options are set, the files in the given path are returned.
183/// If the options include an ignore regex, it is applied to the files returned.
184pub fn paths_from_options(path: &Option<PathBuf>, options: &Option<Options>) -> Vec<PathBuf> {
185 let extension = Some("json");
186 match options {
187 | Some(Options {
188 branch,
189 commit,
190 ignore,
191 merge_request,
192 ..
193 }) => {
194 if *merge_request {
195 match git_branch_name() {
196 | Some(name) => files_from_git_branch(&name, extension),
197 | None => vec![],
198 }
199 } else {
200 match commit {
201 | Some(hash) => files_from_git_commit(hash, extension),
202 | None => match branch {
203 | Some(name) => files_from_git_branch(name, extension),
204 | None => {
205 let value = match path {
206 | Some(x) => x.clone(),
207 | None => PathBuf::from("."),
208 };
209 files_all(value, extension, ignore.clone())
210 }
211 },
212 }
213 }
214 }
215 | None => {
216 let value = match path {
217 | Some(x) => x.clone(),
218 | None => PathBuf::from("."),
219 };
220 files_all(value, extension, None)
221 }
222 }
223}