CustomLintConfigs.parse constructor

CustomLintConfigs.parse(
  1. File? analysisOptionsFile,
  2. PackageConfig packageConfig
)

Decode a CustomLintConfigs from a file.

Implementation

factory CustomLintConfigs.parse(
  File? analysisOptionsFile,
  PackageConfig packageConfig,
) {
  if (analysisOptionsFile == null || !analysisOptionsFile.exists) {
    return CustomLintConfigs.empty;
  }

  final optionsString = analysisOptionsFile.readAsStringSync();
  Object? yaml;
  try {
    yaml = loadYaml(optionsString) as Object?;
  } catch (err) {
    return CustomLintConfigs.empty;
  }
  if (yaml is! Map) return CustomLintConfigs.empty;

  final include = yaml['include'] as Object?;
  var includedOptions = CustomLintConfigs.empty;
  if (include is String) {
    final includeUri = Uri.parse(include);
    String? includeAbsolutePath;

    if (includeUri.scheme == 'package') {
      final packageUri = packageConfig.resolve(includeUri);
      includeAbsolutePath = packageUri?.toFilePath();
    } else {
      includeAbsolutePath = normalize(
        absolute(
          analysisOptionsFile.parent.path,
          includeUri.toFilePath(),
        ),
      );
    }

    if (includeAbsolutePath != null) {
      includedOptions = CustomLintConfigs.parse(
        analysisOptionsFile.provider.getFile(includeAbsolutePath),
        packageConfig,
      );
    }
  }

  final customLint = yaml['custom_lint'] as Object?;
  if (customLint is! Map) return includedOptions;

  final rules = <String, LintOptions>{...includedOptions.rules};
  final enableAllLintRulesYaml = customLint['enable_all_lint_rules'];
  final enableAllLintRules = enableAllLintRulesYaml is bool
      ? enableAllLintRulesYaml
      : includedOptions.enableAllLintRules;

  final debugYaml = customLint['debug'];
  final debug = debugYaml is bool ? debugYaml : includedOptions.debug;

  final verboseYaml = customLint['verbose'];
  final verbose = verboseYaml is bool ? verboseYaml : includedOptions.verbose;

  final rulesYaml = customLint['rules'] as Object?;

  if (rulesYaml is List) {
    // Supports:
    // rules:
    // - prefer_lint
    // - map: false
    // - map2:
    //   length: 42

    for (final item in rulesYaml) {
      if (item is String) {
        rules[item] = const LintOptions.empty(enabled: true);
      } else if (item is Map) {
        final key = item.keys.first as String;
        final value = item.values.first;
        final enabled = value is bool? ? value : null;

        rules[key] = LintOptions.fromYaml(
          Map<String, Object?>.fromEntries(
            item.entries
                .skip(1)
                .map((e) => MapEntry(e.key as String, e.value)),
          ),
          enabled: enabled ?? true,
        );
      }
    }
  }

  return CustomLintConfigs(
    enableAllLintRules: enableAllLintRules,
    verbose: verbose,
    debug: debug,
    rules: UnmodifiableMapView(rules),
  );
}