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