blob: 95d8108d9bb910a152a865ecb335b9f2cd9d7e7b [file] [log] [blame]
// 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;
}
}