Skip to content

Commit 79e8077

Browse files
committed
refactor: use FileSystem service for parallel-safe glob tests and clean up deprecated config APIs
- Add FileSystem service to FilePatternInputProvider for dependency injection - FileSystem.with_base_dir() enables parallel test safety without CWD races - Remove deprecated GlobalConfig::load() and ProjectConfig::load() methods - Convert ignored doctests to runnable examples using MockEnv pattern - Simplify config module docs to show only the current approach
1 parent 71b0cbb commit 79e8077

File tree

8 files changed

+151
-162
lines changed

8 files changed

+151
-162
lines changed

src/config/builder.rs

Lines changed: 25 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,24 @@
1717
//!
1818
//! # Example
1919
//!
20-
//! ```ignore
21-
//! use prodigy::config::builder::load_prodigy_config;
20+
//! ```no_run
21+
//! use prodigy::config::load_prodigy_config;
2222
//!
23-
//! let config = load_prodigy_config()?;
23+
//! let config = load_prodigy_config().expect("failed to load config");
2424
//! println!("Log level: {}", config.log_level);
2525
//! ```
2626
//!
2727
//! # Testing
2828
//!
2929
//! Use `load_prodigy_config_with` with a `MockEnv` for testing:
3030
//!
31-
//! ```ignore
32-
//! use prodigy::config::builder::load_prodigy_config_with;
31+
//! ```
32+
//! use prodigy::config::load_prodigy_config_with;
3333
//! use premortem::MockEnv;
3434
//!
35-
//! let env = MockEnv::new()
36-
//! .with_file("~/.prodigy/config.yml", "log_level: debug")
37-
//! .with_env("PRODIGY_MAX_CONCURRENT_SPECS", "8");
38-
//!
39-
//! let config = load_prodigy_config_with(&env)?;
40-
//! assert_eq!(config.log_level, "debug");
41-
//! assert_eq!(config.max_concurrent_specs, 8);
35+
//! let env = MockEnv::new();
36+
//! let config = load_prodigy_config_with(&env).expect("failed to load config");
37+
//! assert_eq!(config.log_level, "info"); // default value
4238
//! ```
4339
4440
use super::prodigy_config::{global_config_path, project_config_path, ProdigyConfig};
@@ -63,9 +59,11 @@ use premortem::prelude::*;
6359
///
6460
/// # Example
6561
///
66-
/// ```ignore
67-
/// let config = load_prodigy_config()?;
68-
/// println!("Log level: {}", config.log_level); // Deref to ProdigyConfig
62+
/// ```no_run
63+
/// use prodigy::config::load_prodigy_config;
64+
///
65+
/// let config = load_prodigy_config().expect("failed to load config");
66+
/// println!("Log level: {}", config.log_level);
6967
/// ```
7068
pub fn load_prodigy_config() -> Result<Config<ProdigyConfig>, ConfigErrors> {
7169
load_prodigy_config_with(&RealEnv)
@@ -95,20 +93,17 @@ pub fn load_prodigy_config() -> Result<Config<ProdigyConfig>, ConfigErrors> {
9593
///
9694
/// # Example
9795
///
98-
/// ```ignore
96+
/// ```
97+
/// use prodigy::config::load_prodigy_config_with;
9998
/// use premortem::MockEnv;
10099
///
101-
/// let mock = MockEnv::new()
102-
/// .with_file("~/.prodigy/config.yml", r#"
103-
/// log_level: debug
104-
/// max_concurrent_specs: 10
105-
/// "#)
106-
/// .with_env("PRODIGY_AUTO_COMMIT", "false");
100+
/// let env = MockEnv::new()
101+
/// .with_env("PRODIGY__LOG_LEVEL", "debug")
102+
/// .with_env("PRODIGY__MAX_CONCURRENT_SPECS", "10");
107103
///
108-
/// let config = load_prodigy_config_with(&mock)?;
104+
/// let config = load_prodigy_config_with(&env).expect("failed to load");
109105
/// assert_eq!(config.log_level, "debug");
110106
/// assert_eq!(config.max_concurrent_specs, 10);
111-
/// assert!(!config.auto_commit); // env var overrides file
112107
/// ```
113108
pub fn load_prodigy_config_with<E: ConfigEnv>(
114109
env: &E,
@@ -158,13 +153,15 @@ pub fn load_prodigy_config_with<E: ConfigEnv>(
158153
///
159154
/// # Example
160155
///
161-
/// ```ignore
162-
/// let traced = load_prodigy_config_traced()?;
156+
/// ```no_run
157+
/// use prodigy::config::load_prodigy_config_traced;
158+
///
159+
/// let traced = load_prodigy_config_traced().expect("failed to load");
163160
///
164161
/// // See where a value came from
165162
/// if let Some(trace) = traced.trace("max_concurrent_specs") {
166-
/// println!("Value: {}", trace.final_value.value);
167-
/// println!("Source: {}", trace.final_value.source.source);
163+
/// println!("Value: {:?}", trace.final_value.value);
164+
/// println!("Source: {:?}", trace.final_value.source);
168165
/// }
169166
///
170167
/// // Get the actual config

src/config/diagnostics.rs

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66
//!
77
//! # Example
88
//!
9-
//! ```ignore
9+
//! ```
1010
//! use prodigy::config::diagnostics::detect_issues;
11-
//! use prodigy::config::tracing::trace_config;
11+
//! use prodigy::config::tracing::trace_config_with;
12+
//! use premortem::MockEnv;
1213
//!
13-
//! let traced = trace_config()?;
14+
//! let env = MockEnv::new();
15+
//! let traced = trace_config_with(&env).expect("trace failed");
1416
//! let issues = detect_issues(&traced);
1517
//!
16-
//! for issue in issues {
17-
//! println!("Warning: {}", issue.message());
18+
//! for issue in &issues {
19+
//! println!("Warning: {}", issue.message);
1820
//! }
1921
//! ```
2022

src/config/mod.rs

Lines changed: 5 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -55,23 +55,14 @@ pub struct Config {
5555
pub workflow: Option<WorkflowConfig>,
5656
}
5757

58-
/// Global configuration settings for Prodigy.
58+
/// Legacy global configuration settings.
5959
///
60-
/// **Deprecated**: Use [`ProdigyConfig`] with [`load_prodigy_config`] instead.
60+
/// Use [`ProdigyConfig`] with [`load_prodigy_config`] instead:
6161
///
62-
/// These settings apply across all projects and can be overridden
63-
/// by project-specific configuration. Stored in the user's home
64-
/// directory under ~/.prodigy/config.yml.
62+
/// ```no_run
63+
/// use prodigy::config::load_prodigy_config;
6564
///
66-
/// # Migration
67-
///
68-
/// ```ignore
69-
/// // Old approach
70-
/// let global = GlobalConfig::load()?;
71-
/// let api_key = global.claude_api_key;
72-
///
73-
/// // New approach
74-
/// let config = load_prodigy_config()?;
65+
/// let config = load_prodigy_config().expect("load failed");
7566
/// let api_key = config.effective_api_key();
7667
/// ```
7768
#[derive(Debug, Clone, Serialize, Deserialize)]
@@ -129,39 +120,6 @@ impl Default for GlobalConfig {
129120
}
130121

131122
impl GlobalConfig {
132-
/// Load global configuration.
133-
///
134-
/// **Deprecated**: Use [`load_prodigy_config`] instead which provides:
135-
/// - Automatic layered loading (global → project → env)
136-
/// - Comprehensive validation with error accumulation
137-
/// - Source location tracking for errors
138-
///
139-
/// # Migration
140-
///
141-
/// ```ignore
142-
/// // Old approach
143-
/// let global = GlobalConfig::load()?;
144-
///
145-
/// // New approach
146-
/// let config = load_prodigy_config()?;
147-
/// // Access global settings directly from config
148-
/// ```
149-
#[deprecated(since = "0.6.0", note = "Use load_prodigy_config() instead")]
150-
pub fn load() -> Result<Self> {
151-
let config = load_prodigy_config().map_err(|errors| {
152-
anyhow!(
153-
"Failed to load configuration: {}",
154-
errors
155-
.iter()
156-
.map(|e| e.to_string())
157-
.collect::<Vec<_>>()
158-
.join(", ")
159-
)
160-
})?;
161-
162-
Ok(Self::from_prodigy_config(&config))
163-
}
164-
165123
/// Convert from the new ProdigyConfig type to the legacy GlobalConfig.
166124
pub fn from_prodigy_config(config: &ProdigyConfig) -> Self {
167125
GlobalConfig {
@@ -189,39 +147,6 @@ impl GlobalConfig {
189147
}
190148

191149
impl ProjectConfig {
192-
/// Load project configuration.
193-
///
194-
/// **Deprecated**: Use [`load_prodigy_config`] instead which provides:
195-
/// - Automatic layered loading (global → project → env)
196-
/// - Comprehensive validation with error accumulation
197-
/// - Source location tracking for errors
198-
///
199-
/// # Migration
200-
///
201-
/// ```ignore
202-
/// // Old approach
203-
/// let project = ProjectConfig::load()?;
204-
///
205-
/// // New approach
206-
/// let config = load_prodigy_config()?;
207-
/// // Access project settings via config.project
208-
/// ```
209-
#[deprecated(since = "0.6.0", note = "Use load_prodigy_config() instead")]
210-
pub fn load() -> Result<Option<Self>> {
211-
let config = load_prodigy_config().map_err(|errors| {
212-
anyhow!(
213-
"Failed to load configuration: {}",
214-
errors
215-
.iter()
216-
.map(|e| e.to_string())
217-
.collect::<Vec<_>>()
218-
.join(", ")
219-
)
220-
})?;
221-
222-
Ok(config.project.as_ref().map(Self::from_project_settings))
223-
}
224-
225150
/// Convert from the new ProjectSettings type to the legacy ProjectConfig.
226151
pub fn from_project_settings(settings: &ProjectSettings) -> Self {
227152
ProjectConfig {

src/config/prodigy_config.rs

Lines changed: 7 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,46 +6,25 @@
66
//!
77
//! # Example
88
//!
9-
//! ```ignore
10-
//! use prodigy::config::prodigy_config::load_prodigy_config;
9+
//! ```no_run
10+
//! use prodigy::config::load_prodigy_config;
1111
//!
12-
//! // Load from all sources with real I/O
1312
//! let config = load_prodigy_config().expect("config errors");
1413
//! println!("Max concurrent specs: {}", config.max_concurrent_specs);
1514
//! ```
1615
//!
17-
//! # Testing Example
16+
//! # Testing with MockEnv
1817
//!
19-
//! ```ignore
20-
//! use prodigy::config::prodigy_config::load_prodigy_config_with;
18+
//! ```
19+
//! use prodigy::config::load_prodigy_config_with;
2120
//! use premortem::MockEnv;
2221
//!
2322
//! let env = MockEnv::new()
24-
//! .with_file("~/.prodigy/config.yml", "log_level: info")
25-
//! .with_env("PRODIGY_LOG_LEVEL", "debug");
23+
//! .with_env("PRODIGY__LOG_LEVEL", "debug");
2624
//!
27-
//! let config = load_prodigy_config_with(&env).unwrap();
25+
//! let config = load_prodigy_config_with(&env).expect("load failed");
2826
//! assert_eq!(config.log_level, "debug");
2927
//! ```
30-
//!
31-
//! # Migration from GlobalConfig/ProjectConfig
32-
//!
33-
//! This module replaces the older `GlobalConfig` and `ProjectConfig` types with
34-
//! a unified `ProdigyConfig`. The old types still exist for backward compatibility
35-
//! but delegate to this new system.
36-
//!
37-
//! ```ignore
38-
//! // Old approach (deprecated)
39-
//! let global = GlobalConfig::load()?;
40-
//! let project = ProjectConfig::load()?;
41-
//! let api_key = project
42-
//! .and_then(|p| p.claude_api_key.clone())
43-
//! .or_else(|| global.claude_api_key.clone());
44-
//!
45-
//! // New approach
46-
//! let config = load_prodigy_config()?;
47-
//! let api_key = config.effective_api_key(); // Precedence handled internally
48-
//! ```
4928
5029
use premortem::prelude::*;
5130
use serde::{Deserialize, Serialize};

src/config/tracing.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,14 @@
99
//!
1010
//! # Example
1111
//!
12-
//! ```ignore
13-
//! use prodigy::config::tracing::{trace_config, TraceOutput};
12+
//! ```
13+
//! use prodigy::config::tracing::trace_config_with;
14+
//! use premortem::MockEnv;
15+
//!
16+
//! let env = MockEnv::new()
17+
//! .with_env("PRODIGY__LOG_LEVEL", "debug");
1418
//!
15-
//! let traced = trace_config()?;
19+
//! let traced = trace_config_with(&env).expect("trace failed");
1620
//!
1721
//! // Query a specific path
1822
//! if let Some(trace) = traced.trace("log_level") {
@@ -23,9 +27,6 @@
2327
//! for (path, trace) in traced.all_traces() {
2428
//! println!("{}", trace.explain(&path));
2529
//! }
26-
//!
27-
//! // Get JSON output
28-
//! let json = traced.to_json("log_level")?;
2930
//! ```
3031
3132
use premortem::trace::{TracedConfig, ValueTrace};

0 commit comments

Comments
 (0)