Minimal gitconfig parser: finds the value of `key` under `[section]`. Key matching is case-insensitive (git config keys are case-insensitive). Handles `key = value`, `key=value`, and quoted values.
(path: &Path, section: &str, key: &str)
| 1625 | /// Key matching is case-insensitive (git config keys are case-insensitive). |
| 1626 | /// Handles `key = value`, `key=value`, and quoted values. |
| 1627 | fn parse_gitconfig_value(path: &Path, section: &str, key: &str) -> Option<String> { |
| 1628 | let contents = std::fs::read_to_string(path).ok()?; |
| 1629 | let section_lower = section.to_ascii_lowercase(); |
| 1630 | let key_lower = key.to_ascii_lowercase(); |
| 1631 | |
| 1632 | let mut in_section = false; |
| 1633 | for line in contents.lines() { |
| 1634 | let trimmed = line.trim(); |
| 1635 | if trimmed.starts_with('[') { |
| 1636 | // Parse section header: [core], [core "subsection"], etc. |
| 1637 | let header = trimmed |
| 1638 | .trim_start_matches('[') |
| 1639 | .split(']') |
| 1640 | .next() |
| 1641 | .unwrap_or("") |
| 1642 | .trim(); |
| 1643 | let section_name = header.split_whitespace().next().unwrap_or(""); |
| 1644 | in_section = section_name.eq_ignore_ascii_case(§ion_lower); |
| 1645 | continue; |
| 1646 | } |
| 1647 | if !in_section { |
| 1648 | continue; |
| 1649 | } |
| 1650 | if trimmed.is_empty() || trimmed.starts_with('#') || trimmed.starts_with(';') { |
| 1651 | continue; |
| 1652 | } |
| 1653 | // Parse key = value |
| 1654 | if let Some((k, v)) = trimmed.split_once('=') { |
| 1655 | if k.trim().to_ascii_lowercase() == key_lower { |
| 1656 | let v = v.trim(); |
| 1657 | // Strip surrounding quotes if present. |
| 1658 | let v = v |
| 1659 | .strip_prefix('"') |
| 1660 | .and_then(|s| s.strip_suffix('"')) |
| 1661 | .unwrap_or(v); |
| 1662 | return Some(v.to_string()); |
| 1663 | } |
| 1664 | } |
| 1665 | } |
| 1666 | None |
| 1667 | } |
| 1668 | |
| 1669 | /// Appends `core.hooksPath` to the global gitconfig file, creating it if |
| 1670 | /// necessary. Appends to an existing `[core]` section if one exists, |
no test coverage detected