terraform_wrapper/commands/
providers.rs1use crate::Terraform;
2use crate::command::TerraformCommand;
3use crate::error::Result;
4use crate::exec::{self, CommandOutput};
5
6#[derive(Debug, Clone)]
8pub enum ProvidersSubcommand {
9 Default,
11 Lock,
13 Mirror(String),
15 Schema,
17}
18
19#[derive(Debug, Clone)]
46pub struct ProvidersCommand {
47 subcommand: ProvidersSubcommand,
48 platforms: Vec<String>,
49 raw_args: Vec<String>,
50}
51
52impl ProvidersCommand {
53 #[must_use]
55 pub fn new() -> Self {
56 Self {
57 subcommand: ProvidersSubcommand::Default,
58 platforms: Vec::new(),
59 raw_args: Vec::new(),
60 }
61 }
62
63 #[must_use]
65 pub fn lock() -> Self {
66 Self {
67 subcommand: ProvidersSubcommand::Lock,
68 platforms: Vec::new(),
69 raw_args: Vec::new(),
70 }
71 }
72
73 #[must_use]
75 pub fn mirror(target_dir: &str) -> Self {
76 Self {
77 subcommand: ProvidersSubcommand::Mirror(target_dir.to_string()),
78 platforms: Vec::new(),
79 raw_args: Vec::new(),
80 }
81 }
82
83 #[must_use]
85 pub fn schema() -> Self {
86 Self {
87 subcommand: ProvidersSubcommand::Schema,
88 platforms: Vec::new(),
89 raw_args: Vec::new(),
90 }
91 }
92
93 #[must_use]
97 pub fn platform(mut self, platform: &str) -> Self {
98 self.platforms.push(platform.to_string());
99 self
100 }
101
102 #[must_use]
104 pub fn arg(mut self, arg: impl Into<String>) -> Self {
105 self.raw_args.push(arg.into());
106 self
107 }
108}
109
110impl Default for ProvidersCommand {
111 fn default() -> Self {
112 Self::new()
113 }
114}
115
116impl TerraformCommand for ProvidersCommand {
117 type Output = CommandOutput;
118
119 fn args(&self) -> Vec<String> {
120 let mut args = vec!["providers".to_string()];
121 match &self.subcommand {
122 ProvidersSubcommand::Default => {}
123 ProvidersSubcommand::Lock => {
124 args.push("lock".to_string());
125 for platform in &self.platforms {
126 args.push(format!("-platform={platform}"));
127 }
128 }
129 ProvidersSubcommand::Mirror(target_dir) => {
130 args.push("mirror".to_string());
131 for platform in &self.platforms {
132 args.push(format!("-platform={platform}"));
133 }
134 args.push(target_dir.clone());
135 }
136 ProvidersSubcommand::Schema => {
137 args.push("schema".to_string());
138 args.push("-json".to_string());
139 }
140 }
141 args.extend(self.raw_args.clone());
142 args
143 }
144
145 async fn execute(&self, tf: &Terraform) -> Result<CommandOutput> {
146 exec::run_terraform(tf, self.args()).await
147 }
148}
149
150#[cfg(test)]
151mod tests {
152 use super::*;
153
154 #[test]
155 fn default_args() {
156 let cmd = ProvidersCommand::new();
157 assert_eq!(cmd.args(), vec!["providers"]);
158 }
159
160 #[test]
161 fn lock_args() {
162 let cmd = ProvidersCommand::lock();
163 assert_eq!(cmd.args(), vec!["providers", "lock"]);
164 }
165
166 #[test]
167 fn lock_with_platforms() {
168 let cmd = ProvidersCommand::lock()
169 .platform("linux_amd64")
170 .platform("darwin_arm64");
171 let args = cmd.args();
172 assert_eq!(args[0], "providers");
173 assert_eq!(args[1], "lock");
174 assert!(args.contains(&"-platform=linux_amd64".to_string()));
175 assert!(args.contains(&"-platform=darwin_arm64".to_string()));
176 }
177
178 #[test]
179 fn mirror_args() {
180 let cmd = ProvidersCommand::mirror("/tmp/providers");
181 assert_eq!(cmd.args(), vec!["providers", "mirror", "/tmp/providers"]);
182 }
183
184 #[test]
185 fn mirror_with_platform() {
186 let cmd = ProvidersCommand::mirror("/tmp/providers").platform("linux_amd64");
187 assert_eq!(
188 cmd.args(),
189 vec![
190 "providers",
191 "mirror",
192 "-platform=linux_amd64",
193 "/tmp/providers"
194 ]
195 );
196 }
197
198 #[test]
199 fn schema_args() {
200 let cmd = ProvidersCommand::schema();
201 assert_eq!(cmd.args(), vec!["providers", "schema", "-json"]);
202 }
203}