MCPcopy Index your code
hub / github.com/ChrisFeldmeier/OpenCodeRust / resolve_file_references

Function resolve_file_references

crates/opencode-config/src/loader.rs:408–472  ·  view source on GitHub ↗

Resolve `{file:path}` patterns by reading file contents. Skips patterns on commented lines. Resolves relative paths from `base_dir`.

(text: &str, base_dir: &Path)

Source from the content-addressed store, hash-verified

406/// Resolve `{file:path}` patterns by reading file contents.
407/// Skips patterns on commented lines. Resolves relative paths from `base_dir`.
408fn resolve_file_references(text: &str, base_dir: &Path) -> Result<String> {
409 let re = regex::Regex::new(r"\{file:([^}]+)\}").unwrap();
410
411 let mut result = text.to_string();
412
413 // Collect all matches first to avoid borrow issues
414 let matches: Vec<(String, String)> = re
415 .captures_iter(text)
416 .map(|caps| {
417 let full_match = caps.get(0).unwrap().as_str().to_string();
418 let file_path_str = caps[1].to_string();
419 (full_match, file_path_str)
420 })
421 .collect();
422
423 for (full_match, file_path_str) in matches {
424 // Check if the match is on a commented line
425 let match_start = match text.find(&full_match) {
426 Some(pos) => pos,
427 None => continue,
428 };
429 let line_start = text[..match_start].rfind('\n').map(|p| p + 1).unwrap_or(0);
430 let line_end = text[line_start..]
431 .find('\n')
432 .map(|p| line_start + p)
433 .unwrap_or(text.len());
434 let line = &text[line_start..line_end];
435 if line.trim().starts_with("//") {
436 continue;
437 }
438
439 // Resolve the file path
440 let resolved = if file_path_str.starts_with("~/") {
441 dirs::home_dir()
442 .unwrap_or_else(|| PathBuf::from("~"))
443 .join(&file_path_str[2..])
444 } else if Path::new(&file_path_str).is_absolute() {
445 PathBuf::from(&file_path_str)
446 } else {
447 base_dir.join(&file_path_str)
448 };
449
450 // Read the file
451 let content = fs::read_to_string(&resolved).with_context(|| {
452 format!(
453 "bad file reference: \"{}\" - {} does not exist",
454 full_match,
455 resolved.display()
456 )
457 })?;
458 let content = content.trim();
459
460 // Escape for JSON string context (newlines, quotes)
461 let escaped = content
462 .replace('\\', "\\\\")
463 .replace('"', "\\\"")
464 .replace('\n', "\\n")
465 .replace('\r', "\\r")

Calls 6

newFunction · 0.85
home_dirFunction · 0.85
findMethod · 0.80
replaceMethod · 0.80
as_strMethod · 0.45
getMethod · 0.45