Skip to content

Commit 3bab4ac

Browse files
Dillon Nysragingsquirrel3
authored andcommitted
chore(aft): Improve docs error handling + output
1 parent d4920e4 commit 3bab4ac

File tree

5 files changed

+81
-24
lines changed

5 files changed

+81
-24
lines changed

packages/aft/lib/src/commands/amplify_command.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import 'package:aft/src/repo.dart';
99
import 'package:args/command_runner.dart';
1010
import 'package:aws_common/aws_common.dart';
1111
import 'package:checked_yaml/checked_yaml.dart';
12+
import 'package:cli_util/cli_util.dart';
1213
import 'package:collection/collection.dart';
1314
import 'package:git/git.dart' as git;
1415
import 'package:meta/meta.dart';
@@ -211,8 +212,20 @@ abstract class AmplifyCommand extends Command<void>
211212
late final Map<String, String> environment = {
212213
...Platform.environment,
213214
'AFT_ROOT': rootDir.uri.toFilePath(),
215+
// Needed for running `dart doc` for Flutter packages.
216+
if (flutterRoot != null) 'FLUTTER_ROOT': flutterRoot!,
214217
};
215218

219+
/// The path to the Flutter SDK, if installed.
220+
late final String? flutterRoot = () {
221+
final dartSdkPath = getSdkPath();
222+
final flutterBin = p.dirname(p.dirname(dartSdkPath));
223+
if (File(p.join(flutterBin, 'flutter')).existsSync()) {
224+
return p.dirname(flutterBin);
225+
}
226+
return null;
227+
}();
228+
216229
late final Repo repo = Repo(
217230
aftConfig,
218231
logger: logger,

packages/aft/lib/src/commands/docs_command.dart

Lines changed: 61 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@ import 'dart:async';
55
import 'dart:io';
66

77
import 'package:aft/aft.dart';
8+
import 'package:aft/src/options/fail_fast_option.dart';
89
import 'package:aft/src/options/glob_options.dart';
910
import 'package:async/async.dart';
1011
import 'package:aws_common/aws_common.dart';
12+
import 'package:mason_logger/mason_logger.dart';
1113
import 'package:mustache_template/mustache_template.dart';
1214
import 'package:path/path.dart' as p;
1315
import 'package:shelf/shelf_io.dart' as io;
@@ -27,7 +29,11 @@ class DocsCommand extends AmplifyCommand {
2729
String get description => 'Build and deploy API documentation';
2830
}
2931

30-
abstract class _DocsSubcommand extends AmplifyCommand with GlobOptions {
32+
abstract class _DocsSubcommand extends AmplifyCommand
33+
with FailFastOption, GlobOptions {
34+
late final Logger mLogger =
35+
Logger(level: verbose ? Level.verbose : Level.info);
36+
3137
@override
3238
PackageSelector get basePackageSelector {
3339
final currentPackage = workingDirectory.pubspec;
@@ -45,9 +51,15 @@ abstract class _DocsSubcommand extends AmplifyCommand with GlobOptions {
4551
['doc', '--output', output.path],
4652
mode: verbose ? ProcessStartMode.inheritStdio : ProcessStartMode.normal,
4753
workingDirectory: package.path,
54+
environment: environment,
55+
runInShell: true,
4856
);
57+
final error = StringBuffer();
58+
process
59+
..captureStdout(sink: error.write)
60+
..captureStderr(sink: error.write);
4961
if (await process.exitCode != 0) {
50-
throw Exception('Failed to build docs for ${package.name}');
62+
throw Exception('`dart doc` failed for ${package.name}:\n$error');
5163
}
5264
return output;
5365
}
@@ -75,15 +87,19 @@ abstract class _DocsSubcommand extends AmplifyCommand with GlobOptions {
7587

7688
/// Runs pre-build commands if a package uses `code_excerpter` to
7789
/// separate code snippets from docs.
78-
Future<void> _prebuildDocs(PackageInfo package) async {
90+
Future<void> _prebuildDocs(
91+
PackageInfo package, {
92+
Progress? progress,
93+
}) async {
94+
final log = progress?.update ?? mLogger.detail;
7995
final docsPackageDir = Directory(p.join(package.path, 'doc'));
8096
final docsPackage = PackageInfo.fromDirectory(docsPackageDir);
8197
if (docsPackage == null) {
8298
return;
8399
}
84100

85101
// Re-generate code snippet yaml
86-
logger.debug('Re-generating code snippets for ${package.name}...');
102+
log('Re-generating code snippets for ${package.name}...');
87103
await pubAction(package: docsPackage, arguments: ['get']);
88104
await runBuildRunner(
89105
docsPackage,
@@ -93,7 +109,7 @@ abstract class _DocsSubcommand extends AmplifyCommand with GlobOptions {
93109
);
94110

95111
// Update docs with code snippet yaml
96-
logger.debug('Injecting updated code snippets for ${package.name}...');
112+
log('Injecting updated code snippets for ${package.name}...');
97113
await pubAction(package: package, arguments: ['get']);
98114
await pubAction(
99115
package: package,
@@ -109,14 +125,21 @@ abstract class _DocsSubcommand extends AmplifyCommand with GlobOptions {
109125
}
110126

111127
/// Compiles docs for [package] into [outputDir].
112-
Future<Directory> _buildDocs(PackageInfo package, String outputDir) async {
113-
logger.info('Building docs for ${package.name}...');
114-
await _prebuildDocs(package);
128+
Future<Directory> _buildDocs(
129+
PackageInfo package,
130+
String outputDir, {
131+
Progress? progress,
132+
}) async {
133+
progress ??= mLogger.progress('Pre-building docs for ${package.name}');
134+
await _prebuildDocs(package, progress: progress);
135+
progress.update('Running `dart doc` for ${package.name}');
115136
final buildDir = await _dartDoc(package);
116137
final packageOutputDir = Directory(
117138
p.join(outputDir, package.name),
118139
);
140+
progress.update('Copying docs to root dir');
119141
await _copyDir(buildDir, packageOutputDir);
142+
progress.complete('Built docs for ${package.name}!');
120143
return packageOutputDir;
121144
}
122145

@@ -125,25 +148,43 @@ abstract class _DocsSubcommand extends AmplifyCommand with GlobOptions {
125148
if (commandPackages.isEmpty) {
126149
exitError('No packages selected');
127150
}
128-
final packageOutputs = <Map<String, Object?>>[];
151+
final buildOutputs =
152+
FutureGroup<(PackageInfo, Progress, Result<Directory>)>();
129153
for (final package in commandPackages.values) {
130-
final packageOutputDir = await _buildDocs(package, outputDir);
131-
packageOutputs.add({
132-
'name': package.name,
133-
'path': p.relative(package.path, from: rootDir.path),
134-
'link': p.relative(
135-
packageOutputDir.path,
136-
from: outputDir,
137-
),
138-
});
154+
final progress = mLogger.progress('Building docs for ${package.name}');
155+
final buildFuture = _buildDocs(package, outputDir, progress: progress);
156+
buildOutputs.add(
157+
failFast
158+
? buildFuture.then((res) => (package, progress, ValueResult(res)))
159+
: Result.capture(buildFuture)
160+
.then((res) => (package, progress, res)),
161+
);
162+
}
163+
buildOutputs.close();
164+
165+
final packageOutputs = <Map<String, Object?>>[];
166+
for (final (package, progress, buildRes) in await buildOutputs.future) {
167+
switch (buildRes) {
168+
case ValueResult(value: final buildDir):
169+
packageOutputs.add({
170+
'name': package.name,
171+
'path': p.relative(package.path, from: rootDir.path),
172+
'link': p.relative(buildDir.path, from: outputDir),
173+
});
174+
case ErrorResult(:final error, :final stackTrace):
175+
progress.fail('Error building docs for ${package.name}');
176+
mLogger
177+
..err(error.toString())
178+
..err(stackTrace.toString());
179+
}
139180
}
140181
final renderedHtml = Template(_indexTmpl).renderString({
141182
'packages': packageOutputs,
142183
});
143184
final indexFile = File(p.join(outputDir, 'index.html'));
144185
await indexFile.create();
145186
await indexFile.writeAsString(renderedHtml);
146-
logger.info('Successfully built docs');
187+
mLogger.success('Successfully built docs');
147188
}
148189
}
149190

@@ -249,7 +290,7 @@ class _DocsServeSubcommand extends _DocsSubcommand {
249290
}
250291

251292
/// Watches a [package] for changes and calls [onChange] whenever a file is changed.
252-
class _PackageWatcher with Closeable {
293+
class _PackageWatcher implements Closeable {
253294
_PackageWatcher(this.package, {required this.onChange}) {
254295
_listenForEvents();
255296
}

packages/aft/lib/src/commands/publish_command.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,7 @@ Future<void> runBuildRunner(
273273
if (!dartTool.existsSync()) {
274274
await runPub(package.flavor, ['get'], package);
275275
}
276-
logger.info('Running build_runner for ${package.name}...');
276+
logger.debug('Running build_runner for ${package.name}...');
277277
final buildRunnerCmd = await Process.start(
278278
package.flavor.entrypoint,
279279
[

packages/aft/lib/src/pub/pub_runner.dart

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ extension PubAction on AmplifyCommand {
2222
package.flavor,
2323
arguments,
2424
package,
25+
verbose: verbose,
2526
);
2627
} on Exception catch (e) {
2728
final command = this;
@@ -38,13 +39,14 @@ extension PubAction on AmplifyCommand {
3839
Future<void> runPub(
3940
PackageFlavor flavor,
4041
List<String> arguments,
41-
PackageInfo package,
42-
) async {
42+
PackageInfo package, {
43+
bool verbose = false,
44+
}) async {
4345
final proc = await Process.start(
4446
flavor.entrypoint,
4547
['pub', ...arguments],
4648
runInShell: true,
47-
mode: ProcessStartMode.inheritStdio,
49+
mode: verbose ? ProcessStartMode.inheritStdio : ProcessStartMode.normal,
4850
workingDirectory: package.path,
4951
);
5052
final exitCode = await proc.exitCode;

packages/aft/pubspec.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ dependencies:
2424
path: external/libgit2dart
2525
markdown: ^5.0.0
2626
mason: ^0.1.0-dev.40
27+
mason_logger: ^0.2.5
2728
meta: ^1.7.0
2829
mustache_template: ^2.0.0
2930
path: any

0 commit comments

Comments
 (0)