Skip to content

Commit f2c3cb0

Browse files
committed
refactor: implement Builder Pattern for DockerComposeContext
- Introduce DockerComposeContextBuilder for flexible, scalable configuration - Replace specialized constructors (new_sqlite, new_mysql) with unified builder() entry point - Default to SQLite database configuration (zero-config common case) - Explicit database override via with_mysql() method - Consistent optional feature pattern: all use with_* methods - Move Prometheus configuration to builder chain - Update all test code and production code to use new builder API BREAKING CHANGES: - Removed: DockerComposeContext::new_sqlite(ports) - Removed: DockerComposeContext::new_mysql(root_password, database, user, password, port, ports) - Removed: context.with_prometheus(config) post-construction method - New API: DockerComposeContext::builder(ports).build() - MySQL: builder(ports).with_mysql(...).build() - Prometheus: builder(ports).with_prometheus(config).build() Rationale: Previous constructor-based API was "chaotic" with: - Two specialized constructors forcing early database choice - One mutable method (with_prometheus) inconsistent with immutable constructors - Poor scalability: future features (Grafana, Redis) would explode constructor count - Confusing API: when to use constructors vs methods? Builder pattern provides: - Single entry point scales infinitely - SQLite default handles common case with zero config - Explicit database choice via with_mysql() - All optional features via consistent with_* pattern - Clean immutable result after build() - Self-documenting API (builder chain reads like English) - Future-proof: easy to add with_grafana(), with_redis(), etc. This is a complete refactoring with no backward compatibility, justified by: - Project in early development phase - Not used in production by end users yet - Clean migration without technical debt from deprecated APIs - Better developer experience for future contributors
1 parent 010e6fc commit f2c3cb0

File tree

5 files changed

+174
-142
lines changed

5 files changed

+174
-142
lines changed

src/application/steps/rendering/docker_compose_templates.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -152,10 +152,19 @@ impl<S> RenderDockerComposeTemplatesStep<S> {
152152

153153
// Create contexts based on database configuration
154154
let database_config = &self.environment.context().user_inputs.tracker.core.database;
155-
let (env_context, mut docker_compose_context) = match database_config {
155+
let (env_context, docker_compose_context) = match database_config {
156156
DatabaseConfig::Sqlite { .. } => {
157157
let env_context = EnvContext::new(admin_token);
158-
let docker_compose_context = DockerComposeContext::new_sqlite(ports);
158+
159+
let mut builder = DockerComposeContext::builder(ports);
160+
161+
// Add Prometheus configuration if present
162+
if let Some(prometheus_config) = &self.environment.context().user_inputs.prometheus
163+
{
164+
builder = builder.with_prometheus(prometheus_config.clone());
165+
}
166+
167+
let docker_compose_context = builder.build();
159168
(env_context, docker_compose_context)
160169
}
161170
DatabaseConfig::Mysql {
@@ -176,25 +185,26 @@ impl<S> RenderDockerComposeTemplatesStep<S> {
176185
password.clone(),
177186
);
178187

179-
let docker_compose_context = DockerComposeContext::new_mysql(
188+
let mut builder = DockerComposeContext::builder(ports).with_mysql(
180189
root_password,
181190
database_name.clone(),
182191
username.clone(),
183192
password.clone(),
184193
*port,
185-
ports,
186194
);
187195

196+
// Add Prometheus configuration if present
197+
if let Some(prometheus_config) = &self.environment.context().user_inputs.prometheus
198+
{
199+
builder = builder.with_prometheus(prometheus_config.clone());
200+
}
201+
202+
let docker_compose_context = builder.build();
203+
188204
(env_context, docker_compose_context)
189205
}
190206
};
191207

192-
// Add Prometheus configuration if present
193-
if let Some(prometheus_config) = &self.environment.context().user_inputs.prometheus {
194-
docker_compose_context =
195-
docker_compose_context.with_prometheus(prometheus_config.clone());
196-
}
197-
198208
let compose_build_dir = generator
199209
.render(&env_context, &docker_compose_context)
200210
.await?;

src/infrastructure/templating/docker_compose/template/renderer/docker_compose.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -219,14 +219,15 @@ mod tests {
219219
http_tracker_ports: vec![7070],
220220
http_api_port: 1212,
221221
};
222-
let mysql_context = DockerComposeContext::new_mysql(
223-
"rootpass123".to_string(),
224-
"tracker_db".to_string(),
225-
"tracker_user".to_string(),
226-
"userpass123".to_string(),
227-
3306,
228-
ports,
229-
);
222+
let mysql_context = DockerComposeContext::builder(ports)
223+
.with_mysql(
224+
"rootpass123".to_string(),
225+
"tracker_db".to_string(),
226+
"tracker_user".to_string(),
227+
"userpass123".to_string(),
228+
3306,
229+
)
230+
.build();
230231

231232
let renderer = DockerComposeRenderer::new(template_manager);
232233
let output_dir = TempDir::new().unwrap();
@@ -307,7 +308,7 @@ mod tests {
307308
http_tracker_ports: vec![7070],
308309
http_api_port: 1212,
309310
};
310-
let sqlite_context = DockerComposeContext::new_sqlite(ports);
311+
let sqlite_context = DockerComposeContext::builder(ports).build();
311312

312313
let renderer = DockerComposeRenderer::new(template_manager);
313314
let output_dir = TempDir::new().unwrap();
@@ -353,7 +354,9 @@ mod tests {
353354
let prometheus_config = PrometheusConfig {
354355
scrape_interval: 15,
355356
};
356-
let context = DockerComposeContext::new_sqlite(ports).with_prometheus(prometheus_config);
357+
let context = DockerComposeContext::builder(ports)
358+
.with_prometheus(prometheus_config)
359+
.build();
357360

358361
let renderer = DockerComposeRenderer::new(template_manager);
359362
let output_dir = TempDir::new().unwrap();
@@ -421,7 +424,7 @@ mod tests {
421424
http_tracker_ports: vec![7070],
422425
http_api_port: 1212,
423426
};
424-
let context = DockerComposeContext::new_sqlite(ports);
427+
let context = DockerComposeContext::builder(ports).build();
425428

426429
let renderer = DockerComposeRenderer::new(template_manager);
427430
let output_dir = TempDir::new().unwrap();

src/infrastructure/templating/docker_compose/template/renderer/project_generator.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ mod tests {
212212
http_tracker_ports: vec![7070],
213213
http_api_port: 1212,
214214
};
215-
DockerComposeContext::new_sqlite(ports)
215+
DockerComposeContext::builder(ports).build()
216216
}
217217

218218
#[tokio::test]

0 commit comments

Comments
 (0)