dev_scope/models/v1alpha/
doctor_group.rs

1use crate::models::core::ModelMetadata;
2
3use crate::models::v1alpha::V1AlphaApiVersion;
4use crate::models::{HelpMetadata, InternalScopeModel, ScopeModel};
5use derive_builder::Builder;
6use schemars::JsonSchema;
7use serde::{Deserialize, Serialize};
8
9/// What needs to be checked before the action will run. All `paths` will be checked first, then
10/// `commands`. If a `path` has changed, the `command` will not run.
11#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)]
12#[serde(rename_all = "camelCase")]
13#[schemars(deny_unknown_fields)]
14pub struct DoctorCheckSpec {
15    #[serde(default)]
16    /// A list of globs to check for changes. When the glob matches a new file, or the contents
17    /// of the file change, the check will require a fix.
18    pub paths: Option<Vec<String>>,
19
20    #[serde(default)]
21    /// A list of commands to execute to check the environment.
22    pub commands: Option<Vec<String>>,
23}
24
25/// Definition for fixing the environment.
26#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)]
27#[serde(rename_all = "camelCase")]
28#[schemars(deny_unknown_fields)]
29pub struct DoctorFixSpec {
30    #[serde(default)]
31    /// List of commands to run to fix the env.
32    pub commands: Vec<String>,
33
34    #[serde(default)]
35    /// Text to display when no command is provided / fails to fix the env.
36    pub help_text: Option<String>,
37
38    #[serde(default)]
39    /// Link to documentation to fix the issue.
40    pub help_url: Option<String>,
41}
42
43/// An action is a single step used to check in a group. This is most commonly used to build a
44/// series of tasks for a system, like `ruby`, `python`, and databases.
45#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)]
46#[serde(rename_all = "camelCase")]
47#[schemars(deny_unknown_fields)]
48pub struct DoctorGroupActionSpec {
49    /// Name of the "action". When not provided, it will be the index of the action within the group.
50    /// This is used when reporting status to the users.
51    pub name: Option<String>,
52
53    /// A description of this specific action, used for information to the users.
54    pub description: Option<String>,
55
56    /// The `check` run before `fix` (if provided). A check is used to determine if the fix needs
57    /// to be executed, or fail the action if no fix is provided. If a fix is specified, the check
58    /// will re-execute to ensure that the fix applied correctly.
59    pub check: DoctorCheckSpec,
60
61    /// A fix defines how to fix the issue that a `check` is validating. When provided, will only
62    /// run when the `check` "fails".
63    pub fix: Option<DoctorFixSpec>,
64
65    #[serde(default = "doctor_group_action_required_default")]
66    /// If false, the action is allowed to fail and let other actions in the group execute. Defaults
67    /// to `true`.
68    pub required: bool,
69}
70
71fn doctor_group_action_required_default() -> bool {
72    true
73}
74
75/// Often used to describe how to fix a "system", like `ruby`, `python`, or databases. Able to
76/// depend on other "system".
77#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, JsonSchema)]
78#[serde(rename_all = "camelCase")]
79#[schemars(deny_unknown_fields)]
80pub struct DoctorGroupSpec {
81    #[serde(default)]
82    /// A list of `ScopeDoctorGroup` that are required for this group to execute. If not all finish
83    /// successfully, this group will not execute.
84    pub needs: Vec<String>,
85
86    /// A series of steps to check and fix for the group.
87    pub actions: Vec<DoctorGroupActionSpec>,
88}
89
90#[derive(Serialize, Deserialize, Debug, strum::Display, Clone, PartialEq, JsonSchema)]
91pub enum DoctorGroupKind {
92    #[strum(serialize = "ScopeDoctorGroup")]
93    ScopeDoctorGroup,
94}
95
96/// Resource used to define a `ScopeDoctorGroup`.
97#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Builder, JsonSchema)]
98#[builder(setter(into))]
99#[serde(rename_all = "camelCase")]
100#[schemars(deny_unknown_fields)]
101pub struct V1AlphaDoctorGroup {
102    /// API version of the resource
103    pub api_version: V1AlphaApiVersion,
104    /// The type of resource.
105    pub kind: DoctorGroupKind,
106    /// Standard set of options including name, description for the resource.
107    /// Together `kind` and `metadata.name` are required to be unique. If there are duplicate, the
108    /// resources "closest" to the execution dir will take precedence.
109    pub metadata: ModelMetadata,
110    /// Options for the resource.
111    pub spec: DoctorGroupSpec,
112}
113
114impl HelpMetadata for V1AlphaDoctorGroup {
115    fn metadata(&self) -> &ModelMetadata {
116        &self.metadata
117    }
118
119    fn full_name(&self) -> String {
120        format!("{}/{}", self.kind(), self.name())
121    }
122}
123
124impl ScopeModel<DoctorGroupSpec> for V1AlphaDoctorGroup {
125    fn api_version(&self) -> String {
126        Self::int_api_version()
127    }
128
129    fn kind(&self) -> String {
130        Self::int_kind()
131    }
132
133    fn spec(&self) -> &DoctorGroupSpec {
134        &self.spec
135    }
136}
137
138impl InternalScopeModel<DoctorGroupSpec, V1AlphaDoctorGroup> for V1AlphaDoctorGroup {
139    fn int_api_version() -> String {
140        V1AlphaApiVersion::ScopeV1Alpha.to_string()
141    }
142
143    fn int_kind() -> String {
144        DoctorGroupKind::ScopeDoctorGroup.to_string()
145    }
146
147    #[cfg(test)]
148    fn examples() -> Vec<String> {
149        vec!["v1alpha/DoctorGroup.yaml".to_string()]
150    }
151}