Skip to content

Commit 19c7813

Browse files
committed
Pipe all output during generation through pkg/logging
1 parent 1ea7e7b commit 19c7813

9 files changed

+122
-55
lines changed

bin/dartdoc.dart

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import 'package:analyzer/src/dart/sdk/sdk.dart';
1212
import 'package:analyzer/src/generated/sdk.dart';
1313
import 'package:args/args.dart';
1414
import 'package:dartdoc/dartdoc.dart';
15+
import 'package:dartdoc/src/logging.dart';
16+
import 'package:logging/logging.dart' as logging;
1517
import 'package:path/path.dart' as path;
1618
import 'package:stack_trace/stack_trace.dart';
1719

@@ -23,15 +25,15 @@ main(List<String> arguments) async {
2325
try {
2426
args = parser.parse(arguments);
2527
} on FormatException catch (e) {
26-
print(e.message);
27-
print('');
28+
stderr.writeln(e.message);
29+
stderr.writeln('');
2830
// http://linux.die.net/include/sysexits.h
2931
// #define EX_USAGE 64 /* command line usage error */
3032
_printUsageAndExit(parser, exitCode: 64);
3133
}
3234

3335
if (args['help']) {
34-
_printHelp(parser);
36+
_printHelpAndExit(parser);
3537
}
3638

3739
if (args['version']) {
@@ -46,12 +48,9 @@ main(List<String> arguments) async {
4648
}
4749

4850
final bool sdkDocs = args['sdk-docs'];
51+
final bool showProgress = args['show-progress'];
4952

50-
if (args['show-progress']) {
51-
_showProgress = true;
52-
}
53-
54-
var readme = args['sdk-readme'];
53+
final String readme = args['sdk-readme'];
5554
if (readme != null && !(new File(readme).existsSync())) {
5655
stderr.writeln(
5756
" fatal error: unable to locate the SDK description file at $readme.");
@@ -123,6 +122,49 @@ main(List<String> arguments) async {
123122
_printUsageAndExit(parser, exitCode: 1);
124123
}
125124

125+
// By default, get all log output at `progressLevel` or greater.
126+
// This allows us to capture progress events and print `...`.
127+
logging.Logger.root.level = progressLevel;
128+
final stopwatch = new Stopwatch()..start();
129+
130+
// Used to track if we're printing `...` to show progress.
131+
// Allows unified new-line tracking
132+
var writingProgress = false;
133+
134+
logging.Logger.root.onRecord.listen((record) {
135+
if (record.level == progressLevel) {
136+
if (showProgress && stopwatch.elapsed.inMilliseconds > 250) {
137+
writingProgress = true;
138+
stdout.write('.');
139+
stopwatch.reset();
140+
}
141+
return;
142+
}
143+
144+
stopwatch.reset();
145+
if (writingProgress) {
146+
// print a new line after progress dots...
147+
print('');
148+
writingProgress = false;
149+
}
150+
var message = record.message;
151+
assert(message == message.trimRight());
152+
assert(message.isNotEmpty);
153+
154+
if (record.level < logging.Level.WARNING) {
155+
if (message.endsWith('...')) {
156+
// Assume there may be more progress to print, so omit the trailing
157+
// newline
158+
writingProgress = true;
159+
stdout.write(message);
160+
} else {
161+
print(message);
162+
}
163+
} else {
164+
stderr.writeln(message);
165+
}
166+
});
167+
126168
PackageMeta packageMeta = sdkDocs
127169
? new PackageMeta.fromSdk(sdkDir,
128170
sdkReadmePath: readme, useCategories: args['use-categories'])
@@ -144,9 +186,8 @@ main(List<String> arguments) async {
144186
}
145187
}
146188

147-
print("Generating documentation for '${packageMeta}' into "
189+
logInfo("Generating documentation for '${packageMeta}' into "
148190
"${outputDir.absolute.path}${Platform.pathSeparator}");
149-
print('');
150191

151192
var generators = await initGenerators(url, args['rel-canonical-prefix'],
152193
headerFilePaths: headerFilePaths,
@@ -156,8 +197,12 @@ main(List<String> arguments) async {
156197
useCategories: args['use-categories'],
157198
prettyIndexJson: args['pretty-index-json']);
158199

200+
void onProgress(Object file) {
201+
logProgress(file);
202+
}
203+
159204
for (var generator in generators) {
160-
generator.onFileCreated.listen(_onProgress);
205+
generator.onFileCreated.listen(onProgress);
161206
}
162207

163208
DartSdk sdk = new FolderBasedDartSdk(PhysicalResourceProvider.INSTANCE,
@@ -203,10 +248,10 @@ main(List<String> arguments) async {
203248
outputDir, packageMeta, includeLibraries,
204249
includeExternals: includeExternals);
205250

206-
dartdoc.onCheckProgress.listen(_onProgress);
207-
Chain.capture(() async {
251+
dartdoc.onCheckProgress.listen(onProgress);
252+
await Chain.capture(() async {
208253
DartDocResults results = await dartdoc.generateDocs();
209-
print('\nSuccess! Docs generated into ${results.outDir.absolute.path}');
254+
logInfo('Success! Docs generated into ${results.outDir.absolute.path}');
210255
}, onError: (e, Chain chain) {
211256
if (e is DartDocFailure) {
212257
stderr.writeln('\nGeneration failed: ${e}.');
@@ -218,8 +263,6 @@ main(List<String> arguments) async {
218263
});
219264
}
220265

221-
bool _showProgress = false;
222-
223266
ArgParser _createArgsParser() {
224267
var parser = new ArgParser();
225268
parser.addFlag('help',
@@ -232,7 +275,8 @@ ArgParser _createArgsParser() {
232275
defaultsTo: false);
233276
parser.addFlag('sdk-docs',
234277
help: 'Generate ONLY the docs for the Dart SDK.', negatable: false);
235-
parser.addFlag('show-warnings', help: 'Display warnings.', negatable: false);
278+
parser.addFlag('show-warnings',
279+
help: 'Display warnings.', negatable: false, defaultsTo: false);
236280
parser.addFlag('show-progress',
237281
help: 'Display progress indications to console stdout', negatable: false);
238282
parser.addOption('sdk-readme',
@@ -318,17 +362,8 @@ ArgParser _createArgsParser() {
318362
return parser;
319363
}
320364

321-
int _progressCounter = 0;
322-
323-
void _onProgress(var file) {
324-
if (_showProgress && _progressCounter % 5 == 0) {
325-
stdout.write('.');
326-
}
327-
_progressCounter += 1;
328-
}
329-
330365
/// Print help if we are passed the help option.
331-
void _printHelp(ArgParser parser, {int exitCode: 0}) {
366+
void _printHelpAndExit(ArgParser parser, {int exitCode: 0}) {
332367
print('Generate HTML documentation for Dart libraries.\n');
333368
_printUsageAndExit(parser, exitCode: exitCode);
334369
}

lib/dartdoc.dart

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ import 'src/config.dart';
3333
import 'src/generator.dart';
3434
import 'src/html/html_generator.dart';
3535
import 'src/io_utils.dart';
36+
import 'src/logging.dart';
3637
import 'src/model.dart';
3738
import 'src/model_utils.dart';
3839
import 'src/package_meta.dart';
@@ -192,15 +193,15 @@ class DartDoc {
192193
int warnings = package.packageWarningCounter.warningCount;
193194
int errors = package.packageWarningCounter.errorCount;
194195
if (warnings == 0 && errors == 0) {
195-
print("\nno issues found");
196+
logInfo("no issues found");
196197
} else {
197-
print("\nfound ${warnings} ${pluralize('warning', warnings)} "
198+
logWarning("found ${warnings} ${pluralize('warning', warnings)} "
198199
"and ${errors} ${pluralize('error', errors)}");
199200
}
200201

201202
double seconds = _stopwatch.elapsedMilliseconds / 1000.0;
202-
print(
203-
"\ndocumented ${package.libraries.length} librar${package.libraries.length == 1 ? 'y' : 'ies'} "
203+
logInfo(
204+
"Documented ${package.libraries.length} librar${package.libraries.length == 1 ? 'y' : 'ies'} "
204205
"in ${seconds.toStringAsFixed(1)} seconds");
205206

206207
if (package.libraries.isEmpty) {
@@ -420,7 +421,7 @@ class DartDoc {
420421

421422
final Set<String> visited = new Set();
422423
final String start = 'index.html';
423-
stdout.write('\nvalidating docs...');
424+
logInfo('Validating docs...');
424425
_doCheck(package, origin, visited, start);
425426
_doOrphanCheck(package, origin, visited);
426427
_doSearchIndexCheck(package, origin, visited);
@@ -486,7 +487,7 @@ class DartDoc {
486487
name = name.substring(Directory.current.path.length);
487488
if (name.startsWith(Platform.pathSeparator)) name = name.substring(1);
488489
}
489-
print('parsing ${name}...');
490+
logInfo('parsing ${name}...');
490491
JavaFile javaFile = new JavaFile(filePath).getAbsoluteFile();
491492
Source source = new FileBasedSource(javaFile);
492493

@@ -578,12 +579,12 @@ class DartDoc {
578579
..sort();
579580

580581
double seconds = _stopwatch.elapsedMilliseconds / 1000.0;
581-
print("parsed ${libraries.length} ${pluralize('file', libraries.length)} "
582+
logInfo("parsed ${libraries.length} ${pluralize('file', libraries.length)} "
582583
"in ${seconds.toStringAsFixed(1)} seconds");
583584
_stopwatch.reset();
584585

585586
if (errors.isNotEmpty) {
586-
errors.forEach(print);
587+
errors.forEach(logWarning);
587588
int len = errors.length;
588589
throw new DartDocFailure(
589590
"encountered ${len} analysis error${len == 1 ? '' : 's'}");

lib/src/html/html_generator_instance.dart

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44

55
import 'dart:async' show Future, StreamController;
66
import 'dart:convert' show JsonEncoder;
7-
import 'dart:io' show Directory, File, stdout;
7+
import 'dart:io' show Directory, File;
88
import 'dart:typed_data' show Uint8List;
99

1010
import 'package:collection/collection.dart' show compareNatural;
1111
import 'package:path/path.dart' as path;
1212

13+
import '../logging.dart';
1314
import '../model.dart';
1415
import '../warnings.dart';
1516
import 'html_generator.dart' show HtmlGeneratorOptions;
@@ -183,14 +184,13 @@ class HtmlGeneratorInstance implements HtmlOptions {
183184

184185
void generatePackage() {
185186
TemplateData data = new PackageTemplateData(this, package, useCategories);
186-
stdout.write('\ndocumenting ${package.name}');
187+
logInfo('documenting ${package.name}');
187188

188189
_build('index.html', _templates.indexTemplate, data);
189190
}
190191

191192
void generateLibrary(Package package, Library lib) {
192-
stdout
193-
.write('\ngenerating docs for library ${lib.name} from ${lib.path}...');
193+
logInfo('Generating docs for library ${lib.name} from ${lib.path}...');
194194
if (!lib.isAnonymous && !lib.hasDocumentation) {
195195
package.warnOnElement(lib, PackageWarning.noLibraryLevelDocs);
196196
}

lib/src/logging.dart

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Copyright (c) 2017, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:logging/logging.dart';
6+
7+
final _logger = new Logger('dartdoc');
8+
9+
/// A custom [Level] for tracking file writes and verification.
10+
///
11+
/// Has a value of `501` – one more than [Level.FINE].
12+
final Level progressLevel = new Level('progress', 501);
13+
14+
void logWarning(Object message) {
15+
_logger.log(Level.WARNING, message);
16+
}
17+
18+
void logInfo(Object message) {
19+
_logger.log(Level.INFO, message);
20+
}
21+
22+
void logProgress(Object message) {
23+
_logger.log(progressLevel, message);
24+
}

lib/src/model.dart

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import 'package:tuple/tuple.dart';
3030
import 'config.dart';
3131
import 'element_type.dart';
3232
import 'line_number_cache.dart';
33+
import 'logging.dart';
3334
import 'markdown_processor.dart' show Documentation;
3435
import 'model_utils.dart';
3536
import 'package_meta.dart' show PackageMeta, FileContents;
@@ -3116,9 +3117,9 @@ abstract class ModelElement extends Nameable
31163117
// TODO(jcollins-g): move this to Package.warn system
31173118
var filePath =
31183119
this.element.source.fullName.substring(dirPath.length + 1);
3119-
final msg =
3120-
'\nwarning: ${filePath}: @example file not found, ${fragmentFile.path}';
3121-
stderr.write(msg);
3120+
3121+
logWarning(
3122+
'warning: ${filePath}: @example file not found, ${fragmentFile.path}');
31223123
}
31233124
return replacement;
31243125
});

lib/src/package_meta.dart

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import 'dart:io';
99
import 'package:path/path.dart' as path;
1010
import 'package:yaml/yaml.dart';
1111

12+
import 'logging.dart';
13+
1214
abstract class PackageMeta {
1315
final Directory dir;
1416
final bool useCategories;
@@ -103,8 +105,9 @@ class _FilePackageMeta extends PackageMeta {
103105
ProcessResult result =
104106
Process.runSync(pubPath, ['get'], workingDirectory: dir.path);
105107

106-
if (result.stdout.isNotEmpty) {
107-
print(result.stdout.trim());
108+
var trimmedStdout = (result.stdout as String).trim();
109+
if (trimmedStdout.isNotEmpty) {
110+
logInfo(trimmedStdout);
108111
}
109112

110113
if (result.exitCode != 0) {

lib/src/warnings.dart

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import 'dart:io';
2-
31
import 'package:analyzer/dart/element/element.dart';
42
import 'package:tuple/tuple.dart';
53

64
import 'config.dart';
5+
import 'logging.dart';
76

87
class PackageWarningHelpText {
98
final String warningName;
@@ -165,7 +164,7 @@ class PackageWarningCounter {
165164
final _warningCounts = new Map<PackageWarning, int>();
166165
final PackageWarningOptions options;
167166

168-
final _buffer = new StringBuffer();
167+
final _items = <String>[];
169168

170169
PackageWarningCounter(this.options);
171170

@@ -175,8 +174,10 @@ class PackageWarningCounter {
175174
/// warnings here might be duplicated across multiple Package constructions.
176175
void maybeFlush() {
177176
if (options.autoFlush) {
178-
stderr.write(_buffer.toString());
179-
_buffer.clear();
177+
for (var item in _items) {
178+
logWarning(item);
179+
}
180+
_items.clear();
180181
}
181182
}
182183

@@ -192,18 +193,20 @@ class PackageWarningCounter {
192193
toWrite = "warning: ${fullMessage}";
193194
}
194195
if (toWrite != null) {
195-
_buffer.write("\n ${toWrite}");
196+
var entry = " ${toWrite}";
196197
if (_warningCounts[kind] == 1 &&
197198
config.verboseWarnings &&
198199
packageWarningText[kind].longHelp.isNotEmpty) {
199200
// First time we've seen this warning. Give a little extra info.
200201
final String separator = '\n ';
201202
final String nameSub = r'@@name@@';
202203
String verboseOut =
203-
'$separator${packageWarningText[kind].longHelp.join(separator)}';
204-
verboseOut = verboseOut.replaceAll(nameSub, name);
205-
_buffer.write(verboseOut);
204+
'$separator${packageWarningText[kind].longHelp.join(separator)}'
205+
.replaceAll(nameSub, name);
206+
entry = '$entry$verboseOut';
206207
}
208+
assert(entry == entry.trimRight());
209+
_items.add(entry);
207210
}
208211
maybeFlush();
209212
}

pubspec.lock

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,4 +350,4 @@ packages:
350350
source: hosted
351351
version: "2.1.13"
352352
sdks:
353-
dart: ">=1.23.0 <=2.0.0-dev.3.0"
353+
dart: ">=1.23.0 <=2.0.0-dev.5.0"

0 commit comments

Comments
 (0)