Skip to content

Add support for a dartdoc_options.yaml. #1638

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 27 commits into from
Mar 20, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
f733321
Fix or disable miscellaneous lints in dartdoc
jcollins-g Mar 12, 2018
668043e
Merge branch 'master' into fix-lints
jcollins-g Mar 15, 2018
6fedd10
Clean up a few more lints.
jcollins-g Mar 15, 2018
a32fd98
Rename category to package in all remaining references
jcollins-g Mar 15, 2018
b59a4df
dartfmt
jcollins-g Mar 15, 2018
bc64d2c
Review comments
jcollins-g Mar 15, 2018
50475c1
Merge branch 'fix-lints' into category-redo
jcollins-g Mar 15, 2018
6afc18b
Intermediate state
jcollins-g Mar 15, 2018
3ee7464
basic dartdoc options now working
jcollins-g Mar 15, 2018
5500887
Fix test failure (accidentally caching config info)
jcollins-g Mar 15, 2018
1e0fff4
Merge branch 'category-redo' into dartdoc-options-yaml
jcollins-g Mar 15, 2018
65d9d38
dartfmt
jcollins-g Mar 15, 2018
0ddc926
Merge branch 'fix-lints' into category-redo
jcollins-g Mar 15, 2018
a113ef8
dartfmt
jcollins-g Mar 15, 2018
47e3977
Merge branch 'category-redo' into dartdoc-options-yaml
jcollins-g Mar 15, 2018
e9b63db
Merge branch 'master' into fix-lints
jcollins-g Mar 16, 2018
62d30ca
Merge branch 'fix-lints' into category-redo
jcollins-g Mar 16, 2018
014a13f
Merge branch 'category-redo' into dartdoc-options-yaml
jcollins-g Mar 16, 2018
4c57a00
one last rename
jcollins-g Mar 16, 2018
45ff8d9
Merge branch 'category-redo' into dartdoc-options-yaml
jcollins-g Mar 16, 2018
59a50c6
Merge branch 'master' into category-redo
jcollins-g Mar 16, 2018
3737530
Merge branch 'category-redo' into dartdoc-options-yaml
jcollins-g Mar 16, 2018
ffc1149
Merge branch 'master' into dartdoc-options-yaml
jcollins-g Mar 19, 2018
de913dd
Remove overly complicated config inheritance; we can add it back if w…
jcollins-g Mar 19, 2018
76013a6
dartfmt
jcollins-g Mar 19, 2018
5883782
Rename path/p import directive to pathLib everywhere.
jcollins-g Mar 20, 2018
2873935
dartfmt
jcollins-g Mar 20, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions bin/dartdoc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import 'package:args/args.dart';
import 'package:dartdoc/dartdoc.dart';
import 'package:dartdoc/src/logging.dart';
import 'package:logging/logging.dart' as logging;
import 'package:path/path.dart' as path;
import 'package:path/path.dart' as pathLib;
import 'package:stack_trace/stack_trace.dart';

/// Analyzes Dart files and generates a representation of included libraries,
Expand Down Expand Up @@ -112,7 +112,7 @@ main(List<String> arguments) async {
}

Directory outputDir =
new Directory(path.join(Directory.current.path, defaultOutDir));
new Directory(pathLib.join(Directory.current.path, defaultOutDir));
if (args['output'] != null) {
outputDir = new Directory(_resolveTildePath(args['output']));
}
Expand Down Expand Up @@ -421,10 +421,10 @@ String _resolveTildePath(String originalPath) {
String homeDir;

if (Platform.isWindows) {
homeDir = path.absolute(Platform.environment['USERPROFILE']);
homeDir = pathLib.absolute(Platform.environment['USERPROFILE']);
} else {
homeDir = path.absolute(Platform.environment['HOME']);
homeDir = pathLib.absolute(Platform.environment['HOME']);
}

return path.join(homeDir, originalPath.substring(2));
return pathLib.join(homeDir, originalPath.substring(2));
}
48 changes: 24 additions & 24 deletions lib/dartdoc.dart
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import 'package:analyzer/src/generated/source.dart';
import 'package:dartdoc/src/utils.dart';
import 'package:html/dom.dart' show Element, Document;
import 'package:html/parser.dart' show parse;
import 'package:path/path.dart' as path;
import 'package:path/path.dart' as pathLib;

import 'package:tuple/tuple.dart';
import 'src/config.dart';
Expand All @@ -38,7 +38,7 @@ const String name = 'dartdoc';
// Update when pubspec version changes.
const String version = '0.17.1+1';

final String defaultOutDir = path.join('doc', 'api');
final String defaultOutDir = pathLib.join('doc', 'api');

/// Initialize and setup the generators.
Future<List<Generator>> initGenerators(String url, String relCanonicalPrefix,
Expand Down Expand Up @@ -169,7 +169,7 @@ class DartDoc extends PackageBuilder {

for (var generator in generators) {
await generator.generate(packageGraph, outputDir.path);
writtenFiles.addAll(generator.writtenFiles.map(path.normalize));
writtenFiles.addAll(generator.writtenFiles.map(pathLib.normalize));
}
if (config.validateLinks) validateLinks(packageGraph, outputDir.path);
int warnings = packageGraph.packageWarningCounter.warningCount;
Expand Down Expand Up @@ -209,12 +209,12 @@ class DartDoc extends PackageBuilder {
Set<Warnable> warnOnElements;

// Make all paths relative to origin.
if (path.isWithin(origin, warnOn)) {
warnOn = path.relative(warnOn, from: origin);
if (pathLib.isWithin(origin, warnOn)) {
warnOn = pathLib.relative(warnOn, from: origin);
}
if (referredFrom != null) {
if (path.isWithin(origin, referredFrom)) {
referredFrom = path.relative(referredFrom, from: origin);
if (pathLib.isWithin(origin, referredFrom)) {
referredFrom = pathLib.relative(referredFrom, from: origin);
}
// Source paths are always relative.
if (_hrefs[referredFrom] != null) {
Expand Down Expand Up @@ -245,13 +245,13 @@ class DartDoc extends PackageBuilder {

void _doOrphanCheck(
PackageGraph packageGraph, String origin, Set<String> visited) {
String normalOrigin = path.normalize(origin);
String staticAssets = path.joinAll([normalOrigin, 'static-assets', '']);
String indexJson = path.joinAll([normalOrigin, 'index.json']);
String normalOrigin = pathLib.normalize(origin);
String staticAssets = pathLib.joinAll([normalOrigin, 'static-assets', '']);
String indexJson = pathLib.joinAll([normalOrigin, 'index.json']);
bool foundIndexJson = false;
for (FileSystemEntity f
in new Directory(normalOrigin).listSync(recursive: true)) {
var fullPath = path.normalize(f.path);
var fullPath = pathLib.normalize(f.path);
if (f is Directory) {
continue;
}
Expand Down Expand Up @@ -304,8 +304,8 @@ class DartDoc extends PackageBuilder {

void _doSearchIndexCheck(
PackageGraph packageGraph, String origin, Set<String> visited) {
String fullPath = path.joinAll([origin, 'index.json']);
String indexPath = path.joinAll([origin, 'index.html']);
String fullPath = pathLib.joinAll([origin, 'index.json']);
String indexPath = pathLib.joinAll([origin, 'index.html']);
File file = new File("$fullPath");
if (!file.existsSync()) {
return null;
Expand All @@ -320,10 +320,10 @@ class DartDoc extends PackageBuilder {
found.add(indexPath);
for (Map<String, String> entry in jsonData) {
if (entry.containsKey('href')) {
String entryPath = path.joinAll([origin, entry['href']]);
String entryPath = pathLib.joinAll([origin, entry['href']]);
if (!visited.contains(entryPath)) {
_warn(packageGraph, PackageWarning.brokenLink, entryPath,
path.normalize(origin),
pathLib.normalize(origin),
referredFrom: fullPath);
}
found.add(entryPath);
Expand All @@ -333,7 +333,7 @@ class DartDoc extends PackageBuilder {
Set<String> missing_from_search = visited.difference(found);
for (String s in missing_from_search) {
_warn(packageGraph, PackageWarning.missingFromSearchIndex, s,
path.normalize(origin),
pathLib.normalize(origin),
referredFrom: fullPath);
}
}
Expand All @@ -342,14 +342,14 @@ class DartDoc extends PackageBuilder {
String pathToCheck,
[String source, String fullPath]) {
if (fullPath == null) {
fullPath = path.joinAll([origin, pathToCheck]);
fullPath = path.normalize(fullPath);
fullPath = pathLib.joinAll([origin, pathToCheck]);
fullPath = pathLib.normalize(fullPath);
}

Tuple2 stringLinksAndHref = _getStringLinksAndHref(fullPath);
if (stringLinksAndHref == null) {
_warn(packageGraph, PackageWarning.brokenLink, pathToCheck,
path.normalize(origin),
pathLib.normalize(origin),
referredFrom: source);
_onCheckProgress.add(pathToCheck);
// Remove so that we properly count that the file doesn't exist for
Expand All @@ -376,13 +376,13 @@ class DartDoc extends PackageBuilder {
if (uri == null || !uri.hasAuthority && !uri.hasFragment) {
var full;
if (baseHref != null) {
full = '${path.dirname(pathToCheck)}/$baseHref/$href';
full = '${pathLib.dirname(pathToCheck)}/$baseHref/$href';
} else {
full = '${path.dirname(pathToCheck)}/$href';
full = '${pathLib.dirname(pathToCheck)}/$href';
}
var newPathToCheck = path.normalize(full);
String newFullPath = path.joinAll([origin, newPathToCheck]);
newFullPath = path.normalize(newFullPath);
var newPathToCheck = pathLib.normalize(full);
String newFullPath = pathLib.joinAll([origin, newPathToCheck]);
newFullPath = pathLib.normalize(newFullPath);
if (!visited.contains(newFullPath)) {
toVisit.add(new Tuple2(newPathToCheck, newFullPath));
visited.add(newFullPath);
Expand Down
32 changes: 32 additions & 0 deletions lib/src/config.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,38 @@ library dartdoc.config;

import 'dart:io';

import 'package:analyzer/dart/element/element.dart';
import 'package:dartdoc/dartdoc.dart';
import 'package:path/path.dart' as pathLib;

import 'model.dart';

/// Class representing values possibly local to a particular [ModelElement].
class LocalConfig {
final Map<String, Set<String>> categoryMap;
final PackageMeta packageMeta;

LocalConfig._(this.categoryMap, this.packageMeta);

factory LocalConfig.fromLibrary(LibraryElement element) {
return new LocalConfig._({}, getPackageMeta(element));
}

static PackageMeta getPackageMeta(LibraryElement element) {
String sourcePath = element.source.fullName;
File file = new File(pathLib.canonicalize(sourcePath));
Directory dir = file.parent;
while (dir.parent.path != dir.path && dir.existsSync()) {
File pubspec = new File(pathLib.join(dir.path, 'pubspec.yaml'));
if (pubspec.existsSync()) {
return new PackageMeta.fromDir(dir);
}
dir = dir.parent;
}
return null;
}
}

class Config {
final Directory inputDir;
final bool showWarnings;
Expand Down
109 changes: 109 additions & 0 deletions lib/src/dartdoc_options.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
// 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;
}
}
4 changes: 2 additions & 2 deletions lib/src/html/html_generator.dart
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ library dartdoc.html_generator;
import 'dart:async' show Future, StreamController, Stream;
import 'dart:io' show File;

import 'package:path/path.dart' as p;
import 'package:path/path.dart' as pathLib;

import '../generator.dart';
import '../model.dart';
Expand Down Expand Up @@ -82,7 +82,7 @@ class HtmlGenerator extends Generator {
// docs somehow. Check data.self.isCanonical and callers for bugs.
assert(allowOverwrite || !writtenFiles.contains(filePath));

var file = new File(p.join(outputDirectoryPath, filePath));
var file = new File(pathLib.join(outputDirectoryPath, filePath));
var parent = file.parent;
if (!parent.existsSync()) {
parent.createSync(recursive: true);
Expand Down
Loading