Skip to content

Commit f5a92cb

Browse files
committed
Move all printing during run to flow through logging
Tests are no longer noisy on the console Provides a common entry point to provide alternate (JSON) output formats Centralized new-line handling Standardize on stdout for non-fatal output (use of stderr was not consistent)
1 parent 8ced1f6 commit f5a92cb

File tree

8 files changed

+97
-40
lines changed

8 files changed

+97
-40
lines changed

bin/dartdoc.dart

Lines changed: 54 additions & 13 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';
1517
import 'package:path/path.dart' as path;
1618
import 'package:stack_trace/stack_trace.dart';
1719

@@ -47,9 +49,9 @@ main(List<String> arguments) async {
4749

4850
final bool sdkDocs = args['sdk-docs'];
4951

50-
var showProgress = args['show-progress'] as bool;
52+
final showProgress = args['show-progress'] as bool;
5153

52-
var readme = args['sdk-readme'];
54+
var readme = args['sdk-readme'] as String;
5355
if (readme != null && !(new File(readme).existsSync())) {
5456
stderr.writeln(
5557
" fatal error: unable to locate the SDK description file at $readme.");
@@ -121,6 +123,50 @@ main(List<String> arguments) async {
121123
_printUsageAndExit(parser, exitCode: 1);
122124
}
123125

126+
final processLevel = new Level('progress', 299);
127+
Logger.root.level = Level.ALL;
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+
log.onRecord.listen((record) {
135+
try {
136+
if (identical(record.level, processLevel)) {
137+
if (showProgress &&
138+
writingProgress &&
139+
stopwatch.elapsed.inMilliseconds > 500) {
140+
stdout.write('.');
141+
stopwatch.reset();
142+
}
143+
} else {
144+
if (writingProgress) {
145+
// print a new line after progress dots...
146+
print('');
147+
writingProgress = false;
148+
}
149+
var message = record.message;
150+
assert(message == record.message.trimRight());
151+
assert(message.isNotEmpty);
152+
153+
if (message.endsWith('...')) {
154+
// Assume there may be more progress to print, so omit the trailing
155+
// newline
156+
writingProgress = true;
157+
stdout.write(message);
158+
} else {
159+
print(message);
160+
}
161+
}
162+
} catch (e, stack) {
163+
// Errors thrown in logging listeners get swallowed
164+
// Explicitly echoing them here
165+
stderr.writeln('Error while logging:$e\n$stack');
166+
rethrow;
167+
}
168+
});
169+
124170
PackageMeta packageMeta = sdkDocs
125171
? new PackageMeta.fromSdk(sdkDir,
126172
sdkReadmePath: readme, useCategories: args['use-categories'])
@@ -142,9 +188,8 @@ main(List<String> arguments) async {
142188
}
143189
}
144190

145-
print("Generating documentation for '${packageMeta}' into "
191+
log.info("Generating documentation for '${packageMeta}' into "
146192
"${outputDir.absolute.path}${Platform.pathSeparator}");
147-
print('');
148193

149194
var generators = await initGenerators(url, args['rel-canonical-prefix'],
150195
headerFilePaths: headerFilePaths,
@@ -154,13 +199,8 @@ main(List<String> arguments) async {
154199
useCategories: args['use-categories'],
155200
prettyIndexJson: args['pretty-index-json']);
156201

157-
var progressCounter = 0;
158-
159202
void onProgress(Object file) {
160-
if (showProgress && progressCounter % 5 == 0) {
161-
stdout.write('.');
162-
}
163-
progressCounter += 1;
203+
log.log(processLevel, file);
164204
}
165205

166206
for (var generator in generators) {
@@ -211,9 +251,9 @@ main(List<String> arguments) async {
211251
includeExternals: includeExternals);
212252

213253
dartdoc.onCheckProgress.listen(onProgress);
214-
Chain.capture(() async {
254+
await Chain.capture(() async {
215255
DartDocResults results = await dartdoc.generateDocs();
216-
print('\nSuccess! Docs generated into ${results.outDir.absolute.path}');
256+
log.info('Success! Docs generated into ${results.outDir.absolute.path}');
217257
}, onError: (e, Chain chain) {
218258
if (e is DartDocFailure) {
219259
stderr.writeln('\nGeneration failed: ${e}.');
@@ -237,7 +277,8 @@ ArgParser _createArgsParser() {
237277
defaultsTo: false);
238278
parser.addFlag('sdk-docs',
239279
help: 'Generate ONLY the docs for the Dart SDK.', negatable: false);
240-
parser.addFlag('show-warnings', help: 'Display warnings.', negatable: false);
280+
parser.addFlag('show-warnings',
281+
help: 'Display warnings.', negatable: false, defaultsTo: false);
241282
parser.addFlag('show-progress',
242283
help: 'Display progress indications to console stdout', negatable: false);
243284
parser.addOption('sdk-readme',

lib/dartdoc.dart

Lines changed: 10 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+
log.info("no issues found");
196197
} else {
197-
print("\nfound ${warnings} ${pluralize('warning', warnings)} "
198+
log.warning("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+
log.info(
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+
log.info('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+
log.info('parsing ${name}...');
490491
JavaFile javaFile = new JavaFile(filePath).getAbsoluteFile();
491492
Source source = new FileBasedSource(javaFile);
492493

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

580581
double seconds = _stopwatch.elapsedMilliseconds / 1000.0;
581-
print("parsed ${libraries.length} ${pluralize('file', libraries.length)} "
582+
log.info(
583+
"parsed ${libraries.length} ${pluralize('file', libraries.length)} "
582584
"in ${seconds.toStringAsFixed(1)} seconds");
583585
_stopwatch.reset();
584586

585587
if (errors.isNotEmpty) {
586-
errors.forEach(print);
588+
errors.forEach(log.warning);
587589
int len = errors.length;
588590
throw new DartDocFailure(
589591
"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+
log.info('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+
log.info('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: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Copyright (c) 2014, 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+
Logger get log => Logger.root;

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+
log.warning(
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+
log.info(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+
log.warning(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
}

test/compare_output_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ void main() {
145145
final sep = '.'; // We don't care what the path separator character is
146146
final firstUnfoundExample = new RegExp('warning: lib${sep}example.dart: '
147147
'@example file not found.*test_package${sep}dog${sep}food.md');
148-
if (!result.stderr.contains(firstUnfoundExample)) {
148+
if (!result.stdout.contains(firstUnfoundExample)) {
149149
fail('Should warn about unfound @example files: \n'
150150
'stdout:\n${result.stdout}\nstderr:\n${result.stderr}');
151151
}

0 commit comments

Comments
 (0)