| // Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file |
| // for details. All rights reserved. Use of this source code is governed by a |
| // BSD-style license that can be found in the LICENSE file. |
| |
| /// |
| /// dartdoc's dartdoc_options.yaml configuration file follows similar loading |
| /// semantics to that of analysis_options.yaml, |
| /// [documented here](https://www.dartlang.org/guides/language/analysis-options). |
| /// It searches parent directories until it finds an analysis_options.yaml file, |
| /// and uses built-in defaults if one is not found. |
| /// |
| library dartdoc.dartdoc_options; |
| |
| import 'dart:io'; |
| |
| import 'package:path/path.dart' as pathLib; |
| import 'package:yaml/yaml.dart'; |
| |
| import 'logging.dart'; |
| |
| final Map<String, DartdocOptions> _dartdocOptionsCache = {}; |
| |
| abstract class DartdocOptions { |
| DartdocOptions(); |
| |
| /// Path to the dartdoc options file, or '<default>' if this object is the |
| /// default setting. Intended for printing only. |
| String get _path; |
| |
| /// A list indicating the preferred subcategory sorting order. |
| List<String> get categoryOrder; |
| |
| factory DartdocOptions.fromDir(Directory dir) { |
| if (!_dartdocOptionsCache.containsKey(dir.absolute.path)) { |
| _dartdocOptionsCache[dir.absolute.path] = |
| new DartdocOptions._fromDir(dir); |
| } |
| return _dartdocOptionsCache[dir.absolute.path]; |
| } |
| |
| /// Search for a dartdoc_options file in this and parent directories. |
| factory DartdocOptions._fromDir(Directory dir) { |
| if (!dir.existsSync()) return new _DefaultDartdocOptions(); |
| |
| File f; |
| dir = dir.absolute; |
| |
| while (true) { |
| f = new File(pathLib.join(dir.path, 'dartdoc_options.yaml')); |
| if (f.existsSync() || dir.parent.path == dir.path) break; |
| dir = dir.parent.absolute; |
| } |
| |
| DartdocOptions parent; |
| if (dir.parent.path != dir.path) { |
| parent = new DartdocOptions.fromDir(dir.parent); |
| } else { |
| parent = new _DefaultDartdocOptions(); |
| } |
| if (f.existsSync()) { |
| return new _FileDartdocOptions(f); |
| } |
| return parent; |
| } |
| } |
| |
| class _DefaultDartdocOptions extends DartdocOptions { |
| _DefaultDartdocOptions() : super(); |
| |
| @override |
| String get _path => '<default>'; |
| |
| @override |
| List<String> get categoryOrder => new List.unmodifiable([]); |
| } |
| |
| class _FileDartdocOptions extends DartdocOptions { |
| File dartdocOptionsFile; |
| Map _dartdocOptions; |
| _FileDartdocOptions(this.dartdocOptionsFile) : super() { |
| Map allDartdocOptions = loadYaml(dartdocOptionsFile.readAsStringSync()); |
| if (allDartdocOptions.containsKey('dartdoc')) { |
| _dartdocOptions = allDartdocOptions['dartdoc']; |
| } else { |
| _dartdocOptions = {}; |
| logWarning("${_path}: must contain 'dartdoc' section"); |
| } |
| } |
| |
| @override |
| String get _path => dartdocOptionsFile.path; |
| |
| List<String> _categoryOrder; |
| @override |
| List<String> get categoryOrder { |
| if (_categoryOrder == null) { |
| _categoryOrder = []; |
| if (_dartdocOptions.containsKey('categoryOrder')) { |
| if (_dartdocOptions['categoryOrder'] is YamlList) { |
| _categoryOrder.addAll(_dartdocOptions['categoryOrder']); |
| } else { |
| logWarning("${_path}: categoryOrder must be a list (ignoring)"); |
| } |
| } |
| _categoryOrder = new List.unmodifiable(_categoryOrder); |
| } |
| return _categoryOrder; |
| } |
| } |