1use serde::{Deserialize, Serialize};
2
3use crate::types::{DeployTarget, ProjectConfig};
4
5#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
7#[serde(rename_all = "snake_case")]
8pub enum DeployMode {
9 Plan,
10 Run,
11 Verify,
12 Promote,
13 Status,
14 History,
15}
16
17#[derive(Debug, Clone, Serialize, Deserialize)]
18pub struct DeployFlags {
19 pub dry_run: bool,
20 pub skip_oci: bool,
21 #[serde(default)]
23 pub skip_build: bool,
24 #[serde(default)]
27 pub local_image: bool,
28 #[serde(default)]
31 pub require_new_container_image: bool,
32 #[serde(default = "default_true")]
36 pub bootstrap_workload: bool,
37 #[serde(default)]
39 pub doctor: bool,
40 #[serde(default)]
42 pub skip_doctor: bool,
43 pub skip_apply: bool,
44 pub skip_rollout: bool,
45 #[serde(default)]
47 pub skip_expose: bool,
48 pub skip_health: bool,
49 pub yes: bool,
50 pub json: bool,
51 pub namespace: Option<String>,
52 pub context: Option<String>,
53 pub promote_tag: Option<String>,
54 pub history_limit: usize,
55 pub output: Option<std::path::PathBuf>,
56 #[serde(default)]
59 pub destinations: Vec<String>,
60 #[serde(default)]
62 pub only_services: Vec<String>,
63 #[serde(default)]
65 pub exclude_services: Vec<String>,
66}
67
68#[derive(Debug, Clone)]
70pub struct DeployContext {
71 pub env: String,
72 pub target: DeployTarget,
73 pub config: ProjectConfig,
74 pub flags: DeployFlags,
75 pub mode: DeployMode,
76}
77
78fn default_true() -> bool {
79 true
80}
81
82impl Default for DeployFlags {
83 fn default() -> Self {
84 Self {
85 dry_run: false,
86 skip_oci: false,
87 skip_build: false,
88 local_image: false,
89 require_new_container_image: false,
90 bootstrap_workload: true,
91 doctor: false,
92 skip_doctor: false,
93 skip_apply: false,
94 skip_rollout: false,
95 skip_expose: false,
96 skip_health: false,
97 yes: false,
98 json: false,
99 namespace: None,
100 context: None,
101 promote_tag: None,
102 history_limit: 20,
103 output: None,
104 destinations: Vec::new(),
105 only_services: Vec::new(),
106 exclude_services: Vec::new(),
107 }
108 }
109}
110
111impl DeployContext {
112 pub fn require_confirmation(&self) -> bool {
113 if self.flags.yes || self.flags.dry_run {
114 return false;
115 }
116 self.config
117 .kubernetes
118 .as_ref()
119 .map(|k| k.require_context_confirmation_for_apply)
120 .unwrap_or(true)
121 }
122
123 pub fn should_run_doctor(&self) -> bool {
125 if self.flags.skip_doctor || self.flags.dry_run {
126 return false;
127 }
128 self.flags.doctor || matches!(self.mode, DeployMode::Run)
129 }
130}