3
3
// BSD-style license that can be found in the LICENSE file.
4
4
5
5
import 'dart:async' ;
6
+ import 'dart:convert' ;
7
+ import 'dart:io' ;
6
8
7
9
import 'package:logging/logging.dart' ;
10
+ // TODO: export library in pana
11
+ import 'package:pana/src/sdk_env.dart' ;
12
+ import 'package:path/path.dart' as p;
8
13
9
14
import '../shared/task_scheduler.dart' show Task, TaskRunner;
10
15
11
16
final Logger _logger = new Logger ('pub.dartdoc.runner' );
12
17
18
+ const metadataFilePath = 'doc/api/pub-dartlang-metadata.json' ;
19
+
13
20
class DartdocRunner implements TaskRunner {
21
+ String _cachedDartdocVersion;
22
+
14
23
@override
15
24
Future <bool > hasCompletedRecently (Task task) async {
16
25
// TODO: implement a metadata check
@@ -19,7 +28,82 @@ class DartdocRunner implements TaskRunner {
19
28
20
29
@override
21
30
Future <bool > runTask (Task task) async {
22
- // TODO: implement doc generation and upload
23
- return false ; // no race detected
31
+ final tempDir =
32
+ await Directory .systemTemp.createTemp ('pub-dartlang-dartdoc' );
33
+ final tempDirPath = tempDir.resolveSymbolicLinksSync ();
34
+ final pubCacheDir = p.join (tempDirPath, 'pub-cache' );
35
+ final outputDir = p.join (tempDirPath, 'output' );
36
+
37
+ final pubEnv = new PubEnvironment (pubCacheDir: pubCacheDir);
38
+
39
+ try {
40
+ // TODO: use direct link to download the package
41
+ final pkgLocation =
42
+ await pubEnv.getLocation (task.package, version: task.version);
43
+ final pkgPath = pkgLocation.location;
44
+
45
+ // resolve dependencies
46
+ await pubEnv.runUpgrade (pkgPath, /* isFlutter */ false );
47
+
48
+ await _generateDocs (task, pkgPath, outputDir);
49
+
50
+ await _writeMetadata (task, pkgPath);
51
+
52
+ // TODO: upload doc/api to the appropriate bucket
53
+ } finally {
54
+ await tempDir.delete (recursive: true );
55
+ }
56
+ return false ; // no race detection
57
+ }
58
+
59
+ Future _generateDocs (Task task, String pkgPath, String outputDir) async {
60
+ final pr = await Process .run (
61
+ 'dartdoc' ,
62
+ ['--output' , outputDir],
63
+ workingDirectory: pkgPath,
64
+ );
65
+ if (pr.exitCode != 0 ) {
66
+ _logger.severe ('Error while running dartdoc for $task .\n '
67
+ 'exitCode: ${pr .exitCode }\n '
68
+ 'stdout: ${pr .stdout }\n '
69
+ 'stderr: ${pr .stderr }\n ' );
70
+ throw new Exception ('dartdoc execution failed with code ${pr .exitCode }' );
71
+ }
72
+ }
73
+
74
+ Future _writeMetadata (Task task, String pkgPath) async {
75
+ await new File (p.join (pkgPath, metadataFilePath))
76
+ .writeAsString (JSON .encode ({
77
+ 'package' : task.package,
78
+ 'version' : task.version,
79
+ 'dartdoc' : await _getDartdocVersion (),
80
+ 'timestamp' : new DateTime .now ().toUtc ().toIso8601String (),
81
+ }));
82
+ }
83
+
84
+ Future <String > _getDartdocVersion () async {
85
+ if (_cachedDartdocVersion != null ) return _cachedDartdocVersion;
86
+ final pr = await Process .run ('dartdoc' , ['--version' ]);
87
+ if (pr.exitCode != 0 ) {
88
+ _logger.severe ('Unable to detect dartdoc version\n '
89
+ 'exitCode: ${pr .exitCode }\n '
90
+ 'stdout: ${pr .stdout }\n '
91
+ 'stderr: ${pr .stderr }\n ' );
92
+ throw new Exception ('dartdoc execution failed with code ${pr .exitCode }' );
93
+ }
94
+
95
+ final match = _versionRegExp.firstMatch (pr.stdout);
96
+ if (match == null ) {
97
+ _logger.severe ('Unable to parse dartdoc version: ${pr .stdout }' );
98
+ throw new Exception ('Unable to parse dartdoc version: ${pr .stdout }' );
99
+ }
100
+
101
+ final version = match.group (1 ).trim ();
102
+ if (version.isNotEmpty) {
103
+ _cachedDartdocVersion = version;
104
+ }
105
+ return _cachedDartdocVersion;
24
106
}
25
107
}
108
+
109
+ final RegExp _versionRegExp = new RegExp (r'dartdoc version: (.*)$' );
0 commit comments