OLD | NEW |
| (Empty) |
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 /// Convenience methods wrapped up in a class to pull down the docgen viewer for | |
6 /// a viewable website, and start up a server for viewing. | |
7 library docgen.viewer; | |
8 | |
9 import 'dart:io'; | |
10 | |
11 import 'package:path/path.dart' as path; | |
12 | |
13 import 'generator.dart' as gen; | |
14 import 'package_helpers.dart' show rootDirectory; | |
15 | |
16 final String _dartdocViewerString = | |
17 path.join(Directory.current.path, 'dartdoc-viewer'); | |
18 | |
19 final Directory _dartdocViewerDir = new Directory(_dartdocViewerString); | |
20 | |
21 Directory _topLevelTempDir; | |
22 Directory _webDocsDir; | |
23 bool _movedViewerCode = false; | |
24 | |
25 void createViewer(bool serve) { | |
26 _clone(); | |
27 _compile(); | |
28 if (serve) { | |
29 _runServer(); | |
30 } | |
31 } | |
32 | |
33 /* | |
34 * dartdoc-viewer currently has the web app code under a 'client' directory | |
35 * | |
36 * This is confusing for folks that want to clone and modify the code. | |
37 * It also includes a number of python files and other content related to | |
38 * app engine hosting that are not needed. | |
39 * | |
40 * This logic exists to support the current model and a (future) updated | |
41 * dartdoc-viewer repo where the 'client' content exists at the root of the | |
42 * project and the other content is removed. | |
43 */ | |
44 String get _viewerCodePath { | |
45 if (_viewerCodePathCache == null) { | |
46 var pubspecFileName = 'pubspec.yaml'; | |
47 | |
48 var thePath = _dartdocViewerDir.path; | |
49 | |
50 if (!FileSystemEntity.isFileSync(path.join(thePath, pubspecFileName))) { | |
51 thePath = path.join(thePath, 'client'); | |
52 if (!FileSystemEntity.isFileSync(path.join(thePath, pubspecFileName))) { | |
53 throw new StateError('Could not find a pubspec file'); | |
54 } | |
55 } | |
56 | |
57 _viewerCodePathCache = thePath; | |
58 } | |
59 return _viewerCodePathCache; | |
60 } | |
61 String _viewerCodePathCache; | |
62 | |
63 /// If our dartdoc-viewer code is already checked out, move it to a temporary | |
64 /// directory outside of the package directory, so we don't try to process it | |
65 /// for documentation. | |
66 void ensureMovedViewerCode() { | |
67 // TODO(efortuna): This will need to be modified to run on anyone's package | |
68 // outside of the checkout! | |
69 if (_dartdocViewerDir.existsSync()) { | |
70 _topLevelTempDir = new Directory(rootDirectory).createTempSync(); | |
71 _dartdocViewerDir.renameSync(_topLevelTempDir.path); | |
72 } | |
73 } | |
74 | |
75 /// Move the dartdoc-viewer code back into place for "webpage deployment." | |
76 void addBackViewerCode() { | |
77 if (_movedViewerCode) _dartdocViewerDir.renameSync(_dartdocViewerString); | |
78 } | |
79 | |
80 /// Serve up our generated documentation for viewing in a browser. | |
81 void _clone() { | |
82 // If the viewer code is already there, then don't clone again. | |
83 if (_dartdocViewerDir.existsSync()) { | |
84 _moveDirectoryAndServe(); | |
85 } else { | |
86 var processResult = Process.runSync('git', ['clone', '-b', 'master', | |
87 'https://github.com/dart-lang/dartdoc-viewer.git'], runInShell: true); | |
88 | |
89 if (processResult.exitCode == 0) { | |
90 /// Move the generated json/yaml docs directory to the dartdoc-viewer | |
91 /// directory, to run as a webpage. | |
92 var processResult = Process.runSync(gen.pubScript, ['get'], | |
93 runInShell: true, workingDirectory: _viewerCodePath); | |
94 print('process output: ${processResult.stdout}'); | |
95 print('process stderr: ${processResult.stderr}'); | |
96 | |
97 var dir = new Directory(gen.outputDirectory == null ? 'docs' : | |
98 gen.outputDirectory); | |
99 _webDocsDir = new Directory(path.join(_viewerCodePath, 'web', 'docs')); | |
100 if (dir.existsSync()) { | |
101 // Move the docs folder to dartdoc-viewer/client/web/docs | |
102 dir.renameSync(_webDocsDir.path); | |
103 } | |
104 } else { | |
105 print('Error cloning git repository:'); | |
106 print('process output: ${processResult.stdout}'); | |
107 print('process stderr: ${processResult.stderr}'); | |
108 } | |
109 } | |
110 } | |
111 | |
112 /// Move the generated json/yaml docs directory to the dartdoc-viewer | |
113 /// directory, to run as a webpage. | |
114 void _moveDirectoryAndServe() { | |
115 var processResult = Process.runSync(gen.pubScript, ['upgrade'], runInShell: | |
116 true, workingDirectory: path.join(_dartdocViewerDir.path, 'client')); | |
117 print('process output: ${processResult.stdout}'); | |
118 print('process stderr: ${processResult.stderr}'); | |
119 | |
120 var dir = new Directory(gen.outputDirectory == null ? 'docs' : | |
121 gen.outputDirectory); | |
122 var webDocsDir = new Directory(path.join(_dartdocViewerDir.path, 'client', | |
123 'web', 'docs')); | |
124 if (dir.existsSync()) { | |
125 // Move the docs folder to dartdoc-viewer/client/web/docs | |
126 dir.renameSync(webDocsDir.path); | |
127 } | |
128 | |
129 if (webDocsDir.existsSync()) { | |
130 // Compile the code to JavaScript so we can run on any browser. | |
131 print('Compiling the app to JavaScript.'); | |
132 var processResult = Process.runSync(gen.dartBinary, ['deploy.dart'], | |
133 workingDirectory: path.join(_dartdocViewerDir.path, 'client'), | |
134 runInShell: true); | |
135 print('process output: ${processResult.stdout}'); | |
136 print('process stderr: ${processResult.stderr}'); | |
137 _runServer(); | |
138 } | |
139 } | |
140 | |
141 void _compile() { | |
142 if (_webDocsDir.existsSync()) { | |
143 // Compile the code to JavaScript so we can run on any browser. | |
144 print('Compiling the app to JavaScript.'); | |
145 var processResult = Process.runSync(gen.dartBinary, ['deploy.dart'], | |
146 workingDirectory: _viewerCodePath, runInShell: true); | |
147 print('process output: ${processResult.stdout}'); | |
148 print('process stderr: ${processResult.stderr}'); | |
149 var outputDir = path.join(_viewerCodePath, 'out', 'web'); | |
150 print('Docs are available at $outputDir'); | |
151 } | |
152 } | |
153 | |
154 /// A simple HTTP server. Implemented here because this is part of the SDK, | |
155 /// so it shouldn't have any external dependencies. | |
156 void _runServer() { | |
157 // Launch a server to serve out of the directory dartdoc-viewer/client/web. | |
158 HttpServer.bind(InternetAddress.ANY_IP_V6, 8080).then((HttpServer httpServer) | |
159 { | |
160 print('Server launched. Navigate your browser to: ' | |
161 'http://localhost:${httpServer.port}'); | |
162 httpServer.listen((HttpRequest request) { | |
163 var response = request.response; | |
164 var basePath = path.join(_viewerCodePath, 'out', 'web'); | |
165 var requestPath = path.join(basePath, request.uri.path.substring(1)); | |
166 bool found = true; | |
167 var file = new File(requestPath); | |
168 if (file.existsSync()) { | |
169 // Set the correct header type. | |
170 if (requestPath.endsWith('.html')) { | |
171 response.headers.set('Content-Type', 'text/html'); | |
172 } else if (requestPath.endsWith('.js')) { | |
173 response.headers.set('Content-Type', 'application/javascript'); | |
174 } else if (requestPath.endsWith('.dart')) { | |
175 response.headers.set('Content-Type', 'application/dart'); | |
176 } else if (requestPath.endsWith('.css')) { | |
177 response.headers.set('Content-Type', 'text/css'); | |
178 } | |
179 } else { | |
180 if (requestPath == basePath) { | |
181 response.headers.set('Content-Type', 'text/html'); | |
182 file = new File(path.join(basePath, 'index.html')); | |
183 } else { | |
184 print('Path not found: $requestPath'); | |
185 found = false; | |
186 response.statusCode = HttpStatus.NOT_FOUND; | |
187 response.close(); | |
188 } | |
189 } | |
190 | |
191 if (found) { | |
192 // Serve up file contents. | |
193 file.openRead().pipe(response).catchError((e) { | |
194 print('HttpServer: error while closing the response stream $e'); | |
195 }); | |
196 } | |
197 }, onError: (e) { | |
198 print('HttpServer: an error occured $e'); | |
199 }); | |
200 }); | |
201 } | |
OLD | NEW |