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 /// Simple script to generate a page summarizing all error messages produces by | |
6 /// the polymer compiler code. The generated code will be placed directly under | |
7 /// the `polymer/lib/src/generated` folder. This script should be invoked from | |
8 /// the root of the polymer package either by doing: | |
9 /// | |
10 /// dart tool/create_message_details_page.dart | |
11 /// | |
12 /// or | |
13 /// | |
14 /// pub run tool/create_message_details_page | |
15 library polymer.tool.create_message_details_page; | |
16 | |
17 import 'dart:io'; | |
18 import 'dart:mirrors'; | |
19 | |
20 import 'package:code_transformers/messages/messages.dart'; | |
21 import 'package:code_transformers/src/messages.dart' as m1; // used via mirrors | |
22 import 'package:observe/src/messages.dart' as m2; // used via mirrors | |
23 import 'package:polymer/src/build/messages.dart' as m3; // used via mirrors | |
24 import 'package:web_components/build/messages.dart' as m4; // used via mirrors | |
25 import 'package:markdown/markdown.dart'; | |
26 import 'package:path/path.dart' as path; | |
27 import 'package:args/args.dart'; | |
28 | |
29 main(args) { | |
30 var options = _parseOptions(args); | |
31 var seen = {}; | |
32 var templates = []; | |
33 _getMessagesFrom(#polymer.src.build.messages, seen, templates); | |
34 _getMessagesFrom(#code_transformers.src.messages, seen, templates); | |
35 _getMessagesFrom(#observe.src.messages, seen, templates); | |
36 _getMessagesFrom(#web_components.build.messages, seen, templates); | |
37 | |
38 templates.sort((a, b) => a.id.compareTo(b.id)); | |
39 var sb = new StringBuffer(); | |
40 bool forSite = options['site']; | |
41 var out = path.join(path.current, options['out']); | |
42 var ext = forSite ? '.markdown' : '.html'; | |
43 if (!out.endsWith(ext)) { | |
44 print('error: expected to have a $ext extension.'); | |
45 exit(1); | |
46 } | |
47 | |
48 sb.write(forSite ? _SITE_HEADER : _LOCAL_HEADER); | |
49 | |
50 var lastPackage = ''; | |
51 for (var t in templates) { | |
52 if (lastPackage != t.id.package) { | |
53 lastPackage = t.id.package; | |
54 var sectionTitle = '## Messages from package `$lastPackage`\n\n----\n\n'; | |
55 sb.write(forSite ? sectionTitle : markdownToHtml(sectionTitle)); | |
56 } | |
57 _generateMessage(t, forSite, sb); | |
58 } | |
59 sb.write(forSite ? '' : _LOCAL_FOOTER); | |
60 new File(out).writeAsStringSync(sb.toString()); | |
61 print('updated: ${options["out"]}'); | |
62 } | |
63 | |
64 final _mirrors = currentMirrorSystem(); | |
65 | |
66 _getMessagesFrom(Symbol libName, Map seen, List templates) { | |
67 var lib = _mirrors.findLibrary(libName); | |
68 lib.declarations.forEach((symbol, decl) { | |
69 if (decl is! VariableMirror) return; | |
70 var template = lib.getField(symbol).reflectee; | |
71 var name = MirrorSystem.getName(symbol); | |
72 if (template is! MessageTemplate) return; | |
73 var id = template.id; | |
74 if (seen.containsKey(id)) { | |
75 print('error: duplicate id `$id`. ' | |
76 'Currently set for both `$name` and `${seen[id]}`.'); | |
77 } | |
78 seen[id] = name; | |
79 templates.add(template); | |
80 }); | |
81 } | |
82 | |
83 _generateMessage(MessageTemplate template, bool forSite, StringBuffer sb) { | |
84 var details = | |
85 template.details == null ? 'No details available' : template.details; | |
86 if (forSite) details = '{% raw %}$details{% endraw %}'; | |
87 var id = template.id; | |
88 var hashTag = '${id.package}_${id.id}'; | |
89 var title = '### ${template.description} [#${id.id}](#$hashTag)'; | |
90 var body = '\n$details\n\n----\n\n'; | |
91 // We add the anchor inside the <h3> title, otherwise the link doesn't work. | |
92 if (forSite) { | |
93 sb | |
94 ..write(title) | |
95 ..write('\n{: #$hashTag}\n') | |
96 ..write(body); | |
97 } else { | |
98 var html = markdownToHtml('$title$body').replaceFirst('<hr', '</div><hr'); | |
99 sb.write('\n\n<div id="$hashTag">$html'); | |
100 } | |
101 } | |
102 | |
103 _parseOptions(args) { | |
104 var parser = new ArgParser(allowTrailingOptions: true) | |
105 ..addOption('out', | |
106 abbr: 'o', | |
107 defaultsTo: 'lib/src/build/generated/messages.html', | |
108 help: 'the output file path') | |
109 ..addFlag('site', | |
110 abbr: 's', | |
111 negatable: false, | |
112 help: 'generate contents for the dartlang.org site') | |
113 ..addFlag('help', abbr: 'h', negatable: false); | |
114 | |
115 var options = parser.parse(args); | |
116 if (options['help']) { | |
117 var command = Platform.script.path; | |
118 var relPath = path.relative(command, from: path.current); | |
119 if (!relPath.startsWith('../')) command = relPath; | |
120 print('usage: dart $command [-o path_to_output_file] [-s]'); | |
121 print(parser.getUsage()); | |
122 exit(0); | |
123 } | |
124 return options; | |
125 } | |
126 | |
127 const _SITE_HEADER = ''' | |
128 --- | |
129 # WARNING: GENERATED FILE. DO NOT EDIT. | |
130 # | |
131 # This file was generated automatically from the polymer package. | |
132 # To regenerate this file, from the top directory of the polymer package run: | |
133 # | |
134 # dart tool/create_message_details_page.dart -s -o path_to_this_file | |
135 layout: default | |
136 title: "Error Messages" | |
137 subsite: "Polymer.dart" | |
138 description: "Details about error messages from polymer and related packages." | |
139 --- | |
140 | |
141 {% include breadcrumbs.html %} | |
142 | |
143 # {{ page.title }} | |
144 | |
145 <style> | |
146 h3 > a { | |
147 display: none; | |
148 } | |
149 | |
150 h3:hover > a { | |
151 display: inline; | |
152 } | |
153 | |
154 </style> | |
155 | |
156 | |
157 This page contains a list of error messages produced during `pub build` and `pub | |
158 serve` by transformers in polymer and its related packages. You can find here | |
159 additional details that can often help you figure out how to fix the underlying | |
160 problem. | |
161 | |
162 | |
163 '''; | |
164 | |
165 const _LOCAL_HEADER = ''' | |
166 <!doctype html> | |
167 <!-- | |
168 This file is autogenerated with polymer/tool/create_message_details_page.dart | |
169 --> | |
170 <html> | |
171 <style> | |
172 @font-face { | |
173 font-family: 'Montserrat'; | |
174 font-style: normal; | |
175 font-weight: 400; | |
176 src: url(https://themes.googleusercontent.com/static/fonts/montserrat/v4/zhcz-
_WihjSQC0oHJ9TCYL3hpw3pgy2gAi-Ip7WPMi0.woff) format('woff'); | |
177 } | |
178 @font-face { | |
179 font-family: 'Montserrat'; | |
180 font-style: normal; | |
181 font-weight: 700; | |
182 src: url(https://themes.googleusercontent.com/static/fonts/montserrat/v4/IQHow
_FEYlDC4Gzy_m8fcnbFhgvWbfSbdVg11QabG8w.woff) format('woff'); | |
183 } | |
184 @font-face { | |
185 font-family: 'Roboto'; | |
186 font-style: normal; | |
187 font-weight: 300; | |
188 src: url(https://themes.googleusercontent.com/static/fonts/roboto/v10/Hgo13k-t
fSpn0qi1SFdUfbO3LdcAZYWl9Si6vvxL-qU.woff) format('woff'); | |
189 } | |
190 @font-face { | |
191 font-family: 'Roboto'; | |
192 font-style: normal; | |
193 font-weight: 400; | |
194 src: url(https://themes.googleusercontent.com/static/fonts/roboto/v10/CrYjSnGj
rRCn0pd9VQsnFOvvDin1pK8aKteLpeZ5c0A.woff) format('woff'); | |
195 } | |
196 | |
197 body { | |
198 width: 80vw; | |
199 margin: 20px; | |
200 font-family: Roboto, sans-serif; | |
201 background-color: #f0f0f0; | |
202 } | |
203 | |
204 h2 { | |
205 font-family: Montserrat, sans-serif; | |
206 box-sizing: border-box; | |
207 color: rgb(72, 72, 72); | |
208 display: block; | |
209 font-style: normal; | |
210 font-variant: normal; | |
211 font-weight: normal; | |
212 } | |
213 | |
214 div:target { | |
215 background-color: #fff; | |
216 border: 1px solid #888; | |
217 border-radius: 5px; | |
218 padding: 0px 10px 2px 10px; | |
219 box-shadow: 7px 7px 5px #888888; | |
220 margin-bottom: 15px; | |
221 } | |
222 | |
223 | |
224 h3 { | |
225 font-family: Montserrat, sans-serif; | |
226 box-sizing: border-box; | |
227 color: rgb(72, 72, 72); | |
228 display: block; | |
229 font-style: normal; | |
230 font-variant: normal; | |
231 font-weight: normal; | |
232 } | |
233 | |
234 div:target > h3 { | |
235 font-weight: bold; | |
236 } | |
237 | |
238 pre { | |
239 display: block; | |
240 padding: 9.5px; | |
241 margin: 0 0 10px; | |
242 color: #333; | |
243 word-break: break-all; | |
244 word-wrap: break-word; | |
245 background-color: #f5f5f5; | |
246 border: 1px solid #ccc; | |
247 border-radius: 4px; | |
248 } | |
249 | |
250 code { | |
251 font-family: Menlo,Monaco,Consolas,"Courier New",monospace; | |
252 box-sizing: border-box; | |
253 padding: 0; | |
254 font-size: 90%; | |
255 color: #0084c5; | |
256 white-space: nowrap; | |
257 border-radius: 4px; | |
258 background-color: #f9f2f4; | |
259 } | |
260 | |
261 pre code { | |
262 white-space: inherit; | |
263 color: inherit; | |
264 background-color: inherit; | |
265 } | |
266 | |
267 a { | |
268 color: rgb(42, 100, 150); | |
269 } | |
270 | |
271 h3 > a { | |
272 display: none; | |
273 font-size: 0.8em; | |
274 } | |
275 | |
276 h3:hover > a { | |
277 display: inline; | |
278 } | |
279 </style> | |
280 <body> | |
281 '''; | |
282 | |
283 const _LOCAL_FOOTER = ''' | |
284 </body> | |
285 </html> | |
286 '''; | |
OLD | NEW |