(
project_root: &Path,
open_options: TraceDecayOpenOptions,
)
| 191 | } |
| 192 | |
| 193 | pub async fn open_with_options( |
| 194 | project_root: &Path, |
| 195 | open_options: TraceDecayOpenOptions, |
| 196 | ) -> Result<Self> { |
| 197 | let store_layout = |
| 198 | Self::resolve_store_layout_for_project(project_root, &open_options).await?; |
| 199 | let config = load_config_from_path(project_root, &store_layout.config_path)?; |
| 200 | let active_branch = branch::current_branch(project_root); |
| 201 | Self::auto_track_active_branch( |
| 202 | project_root, |
| 203 | &store_layout.data_root, |
| 204 | active_branch.as_deref(), |
| 205 | open_options.clone(), |
| 206 | ) |
| 207 | .await?; |
| 208 | |
| 209 | let (db_path, serving_branch, fallback_warning) = Self::resolve_db_for_branch( |
| 210 | project_root, |
| 211 | &store_layout.data_root, |
| 212 | active_branch.as_deref(), |
| 213 | ); |
| 214 | |
| 215 | if !db_path.exists() { |
| 216 | return Err(TraceDecayError::Config { |
| 217 | message: format!( |
| 218 | "no TraceDecay database found at '{}'; run 'tracedecay init' first", |
| 219 | db_path.display() |
| 220 | ), |
| 221 | }); |
| 222 | } |
| 223 | |
| 224 | // If the dirty sentinel exists, a previous sync/index was interrupted. |
| 225 | // Check integrity and rebuild if necessary. |
| 226 | let crashed = has_dirty_sentinel_at(&store_layout.dirty_path); |
| 227 | if crashed { |
| 228 | eprintln!( |
| 229 | "[tracedecay] previous operation was interrupted — checking database integrity…" |
| 230 | ); |
| 231 | } |
| 232 | |
| 233 | // Try to open; if the database is completely unreadable, delete and |
| 234 | // re-initialize rather than failing permanently. |
| 235 | let open_result = Database::open(&db_path).await; |
| 236 | let (db, migrated) = match open_result { |
| 237 | Ok(pair) => pair, |
| 238 | Err(ref e) if Database::is_corruption_error(e) || crashed => { |
| 239 | print_corruption_warning(); |
| 240 | delete_db_files(&db_path); |
| 241 | clear_dirty_sentinel_at(&store_layout.dirty_path); |
| 242 | let (db, _) = Database::initialize(&db_path).await?; |
| 243 | let ts = Self { |
| 244 | db, |
| 245 | config, |
| 246 | project_root: project_root.to_path_buf(), |
| 247 | store_layout: store_layout.clone(), |
| 248 | open_options: open_options.clone(), |
| 249 | registry: LanguageRegistry::new(), |
| 250 | active_branch: active_branch.clone(), |
nothing calls this directly
no test coverage detected