Skip to content

Commit 611b675

Browse files
authored
command line cleanup and link-to-remote by default (#2187)
* Change default * Link to remote, spinner, doc fixes * Fix dartdoc sanity check * Update README for new outpu * Fix grinder tests
1 parent d647980 commit 611b675

19 files changed

+92
-76
lines changed

README.md

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -20,25 +20,17 @@ For issues/details related to hosted Dart API docs, see
2020

2121
## Generating docs
2222

23-
Run `dartdoc` from the root directory of package. For example:
23+
Run `dartdoc` from the root directory of a package. Here is an example of dartdoc documenting itself:
2424

2525
```
2626
$ dartdoc
27-
Generating documentation for 'server_code_lab' into <path-to-server-code-lab>/server_code_lab/doc/api/
28-
29-
parsing lib/client/piratesapi.dart...
30-
parsing lib/common/messages.dart...
31-
parsing lib/common/utils.dart...
32-
parsing lib/server/piratesapi.dart...
33-
Parsed 4 files in 8.1 seconds.
34-
35-
generating docs for library pirate.messages from messages.dart...
36-
generating docs for library pirate.server from piratesapi.dart...
37-
generating docs for library pirate.utils from utils.dart...
38-
generating docs for library server_code_lab.piratesApi.client from piratesapi.dart...
39-
Documented 4 libraries in 9.6 seconds.
40-
41-
Success! Docs generated into <path-to-server-code-lab>/server_code_lab/doc/api/index.html
27+
Documenting dartdoc...
28+
Initialized dartdoc with 766 libraries in 63.9 seconds
29+
Generating docs for library dartdoc from package:dartdoc/dartdoc.dart...
30+
Validating docs...
31+
no issues found
32+
Documented 1 public library in 17.9 seconds
33+
Success! Docs generated into <path to dartdoc>/doc/api
4234
```
4335

4436
By default, the documentation is generated to the `doc/api` directory as static

lib/dartdoc.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ class Dartdoc extends PackageBuilder {
189189
}
190190

191191
Future<DartdocResults> generateDocs() async {
192-
logPrint("Documenting ${config.topLevelPackageMeta}...");
192+
logInfo("Documenting ${config.topLevelPackageMeta}...");
193193

194194
DartdocResults dartdocResults = await generateDocsBase();
195195
if (dartdocResults.packageGraph.localPublicLibraries.isEmpty) {

lib/src/dartdoc_options.dart

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -205,8 +205,8 @@ class Snapshot {
205205

206206
bool _needsSnapshot = true;
207207

208-
/// Will return true precisely once, unless [toolPath] was already a snapshot.
209-
/// In that case, will always return false.
208+
/// Will return true precisely once, unless [snapshotFile] was already a
209+
/// snapshot. In that case, will always return false.
210210
bool get needsSnapshot {
211211
if (_needsSnapshot == true) {
212212
_needsSnapshot = false;
@@ -1525,18 +1525,14 @@ Future<List<DartdocOption>> createDartdocOptions() async {
15251525
mustExist: true),
15261526
DartdocOptionSet('linkTo')
15271527
..addAll([
1528-
DartdocOptionArgOnly<Map<String, String>>(
1529-
'hosted',
1530-
{
1531-
'pub.dartlang.org':
1532-
'https://pub.dartlang.org/documentation/%n%/%v%'
1533-
},
1528+
DartdocOptionArgOnly<Map<String, String>>('hosted',
1529+
{'pub.dartlang.org': 'https://pub.dev/documentation/%n%/%v%'},
15341530
help: 'Specify URLs for hosted pub packages'),
15351531
DartdocOptionArgOnly<Map<String, String>>(
15361532
'sdks',
15371533
{
1538-
'Dart': 'https://api.dartlang.org/%b%/%v%',
1539-
'Flutter': 'https://docs.flutter.io/flutter',
1534+
'Dart': 'https://api.dart.dev/%b%/%v%',
1535+
'Flutter': 'https://api.flutter.dev/flutter',
15401536
},
15411537
help: 'Specify URLs for SDKs.',
15421538
),
@@ -1558,7 +1554,7 @@ Future<List<DartdocOption>> createDartdocOptions() async {
15581554
}
15591555
return '';
15601556
}, help: 'Url to use for this particular package.'),
1561-
DartdocOptionArgOnly<bool>('remote', false,
1557+
DartdocOptionArgOnly<bool>('remote', true,
15621558
help: 'Allow links to be generated for packages outside this one.',
15631559
negatable: true),
15641560
]),

lib/src/generator/generator_frontend.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ class GeneratorFrontEnd implements Generator {
3636
List<Indexable> indexAccumulator) {
3737
if (packageGraph == null) return;
3838

39-
logInfo('documenting ${packageGraph.defaultPackage.name}');
4039
_generatorBackend.generatePackage(
4140
writer, packageGraph, packageGraph.defaultPackage);
4241

lib/src/logging.dart

Lines changed: 28 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import 'dart:async';
22
import 'dart:convert';
33
import 'dart:io';
44

5+
import 'package:cli_util/cli_logging.dart' show Ansi;
56
import 'package:dartdoc/src/dartdoc_options.dart';
67
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
78
// for details. All rights reserved. Use of this source code is governed by a
@@ -29,6 +30,10 @@ void logInfo(Object message) {
2930
_logger.log(Level.INFO, message);
3031
}
3132

33+
void logDebug(Object message) {
34+
_logger.log(Level.FINE, message);
35+
}
36+
3237
void logProgress(Object message) {
3338
_logger.log(progressLevel, message);
3439
}
@@ -74,41 +79,47 @@ void startLogging(LoggingContext config) {
7479
// Used to track if we're printing `...` to show progress.
7580
// Allows unified new-line tracking
7681
var writingProgress = false;
82+
Ansi ansi = Ansi(Ansi.terminalSupportsAnsi);
83+
int spinnerIndex = 0;
84+
final List<String> spinner = ['-', r'\', '|', '/'];
7785

7886
Logger.root.onRecord.listen((record) {
7987
if (record.level == progressLevel) {
80-
if (config.showProgress && stopwatch.elapsed.inMilliseconds > 250) {
88+
if (!config.quiet &&
89+
config.showProgress &&
90+
stopwatch.elapsed.inMilliseconds > 125) {
91+
if (writingProgress = false) {
92+
stdout.write(' ');
93+
}
8194
writingProgress = true;
82-
stdout.write('.');
95+
stdout.write('${ansi.backspace}${spinner[spinnerIndex]}');
96+
spinnerIndex = (spinnerIndex + 1) % spinner.length;
8397
stopwatch.reset();
8498
}
8599
return;
86100
}
87101

88102
stopwatch.reset();
89103
if (writingProgress) {
90-
// print a new line after progress dots...
91-
print('');
92-
writingProgress = false;
104+
stdout.write('${ansi.backspace} ${ansi.backspace}');
93105
}
94106
var message = record.message;
95107
assert(message == message.trimRight());
96108
assert(message.isNotEmpty);
97109

98110
if (record.level < Level.WARNING) {
99111
if (!config.quiet) {
100-
if (config.showProgress && message.endsWith('...')) {
101-
// Assume there may be more progress to print, so omit the trailing
102-
// newline
103-
writingProgress = true;
104-
stdout.write(message);
105-
} else {
106-
print(message);
107-
}
112+
print(message);
108113
}
109114
} else {
110-
stderr.writeln(message);
115+
if (writingProgress) {
116+
// Some console implementations, like IntelliJ, apparently need
117+
// the backspace to occur for stderr as well.
118+
stderr.write('${ansi.backspace} ${ansi.backspace}');
119+
}
120+
stderr.write('${message}\n');
111121
}
122+
writingProgress = false;
112123
});
113124
}
114125
}
@@ -124,9 +135,9 @@ Future<List<DartdocOption>> createLoggingOptions() async {
124135
DartdocOptionArgOnly<bool>('json', false,
125136
help: 'Prints out progress JSON maps. One entry per line.',
126137
negatable: true),
127-
DartdocOptionArgOnly<bool>('showProgress', false,
128-
help: 'Display progress indications to console stdout',
129-
negatable: false),
138+
DartdocOptionArgOnly<bool>('showProgress', Ansi.terminalSupportsAnsi,
139+
help: 'Display progress indications to console stdout.',
140+
negatable: true),
130141
DartdocOptionArgSynth<bool>('quiet',
131142
(DartdocSyntheticOption option, Directory dir) {
132143
if (option.root['generateDocs']?.valueAt(dir) == false) {

lib/src/model/class.dart

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ class Class extends Container
9191

9292
Map<String, List<ModelElement>> _allModelElementsByNamePart;
9393

94-
/// Helper for [_MarkdownCommentReference._getResultsForClass].
94+
/// Helper for `_MarkdownCommentReference._getResultsForClass`.
9595
Map<String, List<ModelElement>> get allModelElementsByNamePart {
9696
if (_allModelElementsByNamePart == null) {
9797
_allModelElementsByNamePart = {};
@@ -435,8 +435,6 @@ class Class extends Container
435435

436436
List<Field> _fields;
437437

438-
/// Internal only because subclasses are allowed to override how
439-
/// these are mapped to [allInheritedFields] and so forth.
440438
@override
441439
List<Field> get allFields {
442440
if (_fields == null) {

lib/src/model/inheritable.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import 'package:dartdoc/src/special_elements.dart';
1616
/// namespace, that's the one we should treat as canonical and implementors
1717
/// of this class can use that knowledge to determine canonicalization.
1818
///
19-
/// We pick the class closest to the [definingEnclosingElement] so that all
19+
/// We pick the class closest to the [definingEnclosingContainer] so that all
2020
/// children of that class inheriting the same member will point to the same
2121
/// place in the documentation, and we pick a canonical class because that's
2222
/// the one in the public namespace that will be documented.

lib/src/model/locatable.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
// for details. All rights reserved. Use of this source code is governed by a
33
// BSD-style license that can be found in the LICENSE file.
44

5+
import 'package:analyzer/dart/element/element.dart' show Element;
6+
57
/// Something that can be located for warning purposes.
68
abstract class Locatable {
79
List<Locatable> get documentationFrom;

lib/src/model/model_element.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,7 @@ abstract class ModelElement extends Canonicalization
744744

745745
@override
746746
bool get isCanonical {
747+
if (!isPublic) return false;
747748
if (library == canonicalLibrary) {
748749
if (this is Inheritable) {
749750
Inheritable i = (this as Inheritable);

lib/src/model/nameable.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ abstract class Nameable {
2424

2525
String _namePart;
2626

27-
/// Utility getter/cache for [_MarkdownCommentReference._getResultsForClass].
27+
/// Utility getter/cache for `_MarkdownCommentReference._getResultsForClass`.
2828
String get namePart {
2929
// TODO(jcollins-g): This should really be the same as 'name', but isn't
3030
// because of accessors and operators.

lib/src/model/never.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ class NeverType extends ModelElement {
99
NeverType(Element element, PackageGraph packageGraph)
1010
: super(element, null, packageGraph, null);
1111

12-
/// [never] is not a real object, and so we can't document it, so there
12+
/// `Never` is not a real object, and so we can't document it, so there
1313
/// can be nothing canonical for it.
1414
@override
1515
ModelElement get canonicalModelElement => null;

lib/src/model/package.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,9 @@ class Package extends LibraryContainer
147147

148148
bool _isLocal;
149149

150-
/// Return true if this is the default package, this is part of an embedder SDK,
151-
/// or if [config.autoIncludeDependencies] is true -- but only if the package
152-
/// was not excluded on the command line.
150+
/// Return true if this is the default package, this is part of an embedder
151+
/// SDK, or if [DartdocOptionContext.autoIncludeDependencies] is true -- but
152+
/// only if the package was not excluded on the command line.
153153
bool get isLocal {
154154
if (_isLocal == null) {
155155
_isLocal = (

lib/src/model/package_builder.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ class PackageBuilder {
163163
null,
164164
sourceFactory,
165165
options);
166-
driver.results.listen((_) {});
166+
driver.results.listen((_) => logProgress(''));
167167
driver.exceptions.listen((_) {});
168168
scheduler.start();
169169
}
@@ -243,11 +243,12 @@ class PackageBuilder {
243243
// Be careful here not to accidentally stack up multiple
244244
// ResolvedLibraryResults, as those eat our heap.
245245
for (String f in files) {
246+
logProgress(f);
246247
ResolvedLibraryResult r = await processLibrary(f);
247248
if (r != null &&
248249
!libraries.contains(r.element) &&
249250
isLibraryIncluded(r.element)) {
250-
logInfo('parsing ${f}...');
251+
logDebug('parsing ${f}...');
251252
libraryAdder(r);
252253
libraries.add(r.element);
253254
}

lib/src/model/package_graph.dart

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:analyzer/src/generated/source.dart';
1414
import 'package:analyzer/src/generated/source_io.dart';
1515
import 'package:collection/collection.dart';
1616
import 'package:dartdoc/src/dartdoc_options.dart';
17+
import 'package:dartdoc/src/logging.dart';
1718
import 'package:dartdoc/src/model/model.dart';
1819
import 'package:dartdoc/src/model_utils.dart' as utils;
1920
import 'package:dartdoc/src/package_meta.dart' show PackageMeta;
@@ -103,11 +104,13 @@ class PackageGraph {
103104
!precachedElements.contains(d)) {
104105
precachedElements.add(d);
105106
yield d.precacheLocalDocs();
107+
logProgress(d.name);
106108
// TopLevelVariables get their documentation from getters and setters,
107109
// so should be precached if either has a template.
108110
if (m is TopLevelVariable && !precachedElements.contains(m)) {
109111
precachedElements.add(m);
110112
yield m.precacheLocalDocs();
113+
logProgress(d.name);
111114
}
112115
}
113116
}

lib/src/model/top_level_container.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import 'package:dartdoc/src/model/model.dart';
66
import 'package:dartdoc/src/model_utils.dart' as model_utils;
77

88
/// A set of [Class]es, [Enum]s, [TopLevelVariable]s, [ModelFunction]s,
9-
/// [Property]s, and [Typedef]s, possibly initialized after construction by
9+
/// [Field]s, and [Typedef]s, possibly initialized after construction by
1010
/// accessing private member variables. Do not call any methods or members
1111
/// excepting [name] and the private Lists below before finishing initialization
1212
/// of a [TopLevelContainer].

pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ dependencies:
1010
analyzer: ^0.39.6
1111
args: '>=1.5.0 <2.0.0'
1212
collection: ^1.2.0
13+
cli_util: ^0.1.3+2
1314
crypto: ^2.0.6
1415
html: '>=0.12.1 <0.15.0'
1516
# We don't use http_parser directly; this dep exists to ensure that we get at

test/dartdoc_test.dart

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -211,8 +211,7 @@ void main() {
211211
});
212212

213213
test('basic interlinking test', () async {
214-
Dartdoc dartdoc =
215-
await buildDartdoc(['--link-to-remote'], testPackageDir, tempDir);
214+
Dartdoc dartdoc = await buildDartdoc([], testPackageDir, tempDir);
216215
DartdocResults results = await dartdoc.generateDocs();
217216
PackageGraph p = results.packageGraph;
218217
Package meta = p.publicPackages.firstWhere((p) => p.name == 'meta');
@@ -228,9 +227,9 @@ void main() {
228227
expect(
229228
useSomethingInAnotherPackage.modelType.linkedName,
230229
matches(
231-
'<a href=\"https://pub.dartlang.org/documentation/meta/[^\"]*/meta/Required-class.html\">Required</a>'));
230+
'<a href=\"https://pub.dev/documentation/meta/[^\"]*/meta/Required-class.html\">Required</a>'));
232231
RegExp stringLink = RegExp(
233-
'https://api.dartlang.org/(dev|stable|edge|be)/${Platform.version.split(' ').first}/dart-core/String-class.html">String</a>');
232+
'https://api.dart.dev/(dev|stable|edge|be|beta)/${Platform.version.split(' ').first}/dart-core/String-class.html">String</a>');
234233
expect(useSomethingInTheSdk.modelType.linkedName, contains(stringLink));
235234
});
236235

test/src/utils.dart

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,29 +28,42 @@ PackageMeta sdkPackageMeta = PackageMeta.fromDir(sdkDir);
2828

2929
final _testPackageGraphMemo = AsyncMemoizer<PackageGraph>();
3030
Future<PackageGraph> get testPackageGraph => _testPackageGraphMemo.runOnce(() =>
31-
bootBasicPackage('testing/test_package', ['css', 'code_in_comments']));
31+
bootBasicPackage('testing/test_package', ['css', 'code_in_comments'],
32+
additionalArguments: ['--no-link-to-remote']));
3233

3334
final _testPackageGraphExperimentsMemo = AsyncMemoizer<PackageGraph>();
3435
Future<PackageGraph> get testPackageGraphExperiments =>
3536
_testPackageGraphExperimentsMemo.runOnce(() => bootBasicPackage(
36-
'testing/test_package_experiments', [],
37-
additionalArguments: ['--enable-experiment', 'non-nullable']));
37+
'testing/test_package_experiments', [], additionalArguments: [
38+
'--enable-experiment',
39+
'non-nullable',
40+
'--no-link-to-remote'
41+
]));
3842

3943
final _testPackageGraphGinormousMemo = AsyncMemoizer<PackageGraph>();
4044
Future<PackageGraph> get testPackageGraphGinormous =>
4145
_testPackageGraphGinormousMemo.runOnce(() => bootBasicPackage(
42-
'testing/test_package', ['css', 'code_in_commnets', 'excluded'],
43-
additionalArguments: ['--auto-include-dependencies']));
46+
'testing/test_package', [
47+
'css',
48+
'code_in_commnets',
49+
'excluded'
50+
], additionalArguments: [
51+
'--auto-include-dependencies',
52+
'--no-link-to-remote'
53+
]));
4454

4555
final _testPackageGraphSmallMemo = AsyncMemoizer<PackageGraph>();
46-
Future<PackageGraph> get testPackageGraphSmall => _testPackageGraphSmallMemo
47-
.runOnce(() => bootBasicPackage('testing/test_package_small', []));
56+
Future<PackageGraph> get testPackageGraphSmall =>
57+
_testPackageGraphSmallMemo.runOnce(() => bootBasicPackage(
58+
'testing/test_package_small', [],
59+
additionalArguments: ['--no-link-to-remote']));
4860

4961
final _testPackageGraphErrorsMemo = AsyncMemoizer<PackageGraph>();
5062
Future<PackageGraph> get testPackageGraphErrors =>
5163
_testPackageGraphErrorsMemo.runOnce(() => bootBasicPackage(
5264
'testing/test_package_doc_errors',
53-
['css', 'code_in_comments', 'excluded']));
65+
['css', 'code_in_comments', 'excluded'],
66+
additionalArguments: ['--no-link-to-remote']));
5467

5568
final _testPackageGraphSdkMemo = AsyncMemoizer<PackageGraph>();
5669
Future<PackageGraph> get testPackageGraphSdk =>

0 commit comments

Comments
 (0)