check method

Validates both config files with the real section parsers. Missing files are fine (defaults apply); syntax errors, strict-section schema errors and bad scalar types are errors; unknown top-level keys are warnings (the runtime silently ignores them — the check does not).

Implementation

Future<ConfigCheckReport> check() async {
  final report = ConfigCheckReport();
  final globalPath = globalConfigPath;
  if (globalPath == null) {
    report.notes.add(
      'global scope unavailable on this host (no home directory)',
    );
  } else {
    final text = await _readTextOrNull(globalPath);
    if (text == null) {
      report.notes.add('global config absent (defaults apply): $globalPath');
    } else {
      _collectDiagnostics(text, globalPath, report.errors, report.warnings);
      _collectHostWarnings(_tryParse(text), globalPath, report.warnings);
    }
  }
  final projectText = await _readTextOrNull(projectConfigPath);
  if (projectText == null) {
    report.notes.add(
      'project config absent (defaults apply): $projectConfigPath',
    );
  } else {
    final projectWarnings = <ConfigDiagnostic>[];
    _collectDiagnostics(
      projectText,
      projectConfigPath,
      report.errors,
      projectWarnings,
    );
    report.warnings.addAll(projectWarnings);
    // Dead config: sections the project file is never read for.
    final doc = _tryParse(projectText);
    if (doc != null) {
      for (final key in doc.keys) {
        if (!_projectSections.contains('$key')) {
          report.warnings.add(
            ConfigDiagnostic(
              projectConfigPath,
              '"$key" in the project file is dead config — only '
              '${_projectSections.join('/')} are read from here',
            ),
          );
        }
      }
    }
    _collectHostWarnings(doc, projectConfigPath, report.warnings);
  }
  return report;
}