Index: packages/polymer/bin/new_entry.dart |
diff --git a/packages/polymer/bin/new_entry.dart b/packages/polymer/bin/new_entry.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..a1abf22e4b5a4b2472d2fb8be461aa8b3b668900 |
--- /dev/null |
+++ b/packages/polymer/bin/new_entry.dart |
@@ -0,0 +1,207 @@ |
+// Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+/// Script to create boilerplate for a Polymer element. |
+/// Produces new .html entry point for a polymer app and updates the |
+/// pubspec.yaml to reflect it. |
+/// |
+/// Run this script with pub run: |
+/// |
+/// pub run polymer:new_entry <html_file> |
+/// |
+library polymer.bin.new_entry; |
+ |
+import 'dart:io'; |
+import 'package:args/args.dart'; |
+import 'package:path/path.dart' as path; |
+import 'package:yaml/yaml.dart'; |
+import 'package:source_span/source_span.dart'; |
+ |
+void printUsage() { |
+ print('pub run polymer:new_entry entry_point_file.html'); |
+} |
+ |
+void main(List<String> args) { |
+ var parser = new ArgParser(allowTrailingOptions: true); |
+ parser.addFlag('help', abbr: 'h'); |
+ var entryPoint; |
+ |
+ try { |
+ var options = parser.parse(args); |
+ if (options['help']) { |
+ printUsage(); |
+ return; |
+ } |
+ entryPoint = options.rest[0]; |
+ } catch (e) { |
+ print('$e\n'); |
+ printUsage(); |
+ exitCode = 1; |
+ return; |
+ } |
+ |
+ // If the entrypoint file has no extension, add .html to it. |
+ if (path.extension(entryPoint) == '') { |
+ entryPoint = '${entryPoint}.html'; |
+ } |
+ |
+ var outputDir = path.dirname(entryPoint); |
+ var outputDirLocation = new Directory(outputDir); |
+ |
+ if (!outputDirLocation.existsSync()) { |
+ outputDirLocation.createSync(recursive: true); |
+ } |
+ |
+ outputDir = outputDirLocation.resolveSymbolicLinksSync(); |
+ var pubspecDir = _findDirWithFile(outputDir, 'pubspec.yaml'); |
+ |
+ if (pubspecDir == null) { |
+ print('Could not find pubspec.yaml when walking up from $outputDir'); |
+ exitCode = 1; |
+ return; |
+ } |
+ |
+ var relativeEntryPoint = path.relative( |
+ path.join(outputDir, path.basename(entryPoint)), from: pubspecDir); |
+ |
+ try { |
+ if (_createBoilerPlate(relativeEntryPoint, pubspecDir)) { |
+ print('Added $entryPoint to ${path.join(pubspecDir, "pubspec.yaml")}'); |
+ } |
+ print('Successfully created:'); |
+ print(' ' + path.join(pubspecDir, entryPoint)); |
+ } catch (e, t) { |
+ print('Exception: $e\n$t'); |
+ print('Error creating files in $outputDir'); |
+ exitCode = 1; |
+ } |
+ |
+ return; |
+} |
+ |
+String _findDirWithFile(String dir, String filename) { |
+ while (!new File(path.join(dir, filename)).existsSync()) { |
+ var parentDir = path.dirname(dir); |
+ // If we reached root and failed to find it, bail. |
+ if (parentDir == dir) return null; |
+ dir = parentDir; |
+ } |
+ return dir; |
+} |
+ |
+// Returns true if the pubspec file was modified. It might not be modified if |
+// there was a monolithic polymer transformer in the pubspec, or if the entry |
+// point for some reason already existed in the pubspec. |
+bool _createBoilerPlate(String entryPoint, String pubspecDir) { |
+ String html = ''' |
+<!doctype html> |
+<html> |
+ <head> |
+ <!-- link rel="import" href="path_to_html_import.html" --> |
+ </head> |
+ <body> |
+ <!-- HTML for body here --> |
+ <script type="application/dart">export 'package:polymer/init.dart';</script> |
+ </body> |
+</html> |
+'''; |
+ |
+ new File(path.join(pubspecDir, entryPoint)).writeAsStringSync(html); |
+ |
+ var pubspecPath = path.join(pubspecDir, 'pubspec.yaml'); |
+ var pubspecText = new File(pubspecPath).readAsStringSync(); |
+ var transformers = loadYaml(pubspecText)['transformers']; |
+ var entryPoints; |
+ |
+ var insertionPoint; |
+ var textToInsert = ''; |
+ |
+ if (transformers != null) { |
+ // If there are transformers in the pubspec, look for the polymer |
+ // transformers, get the entry points, and delete the old entry points. |
+ SourceSpan transformersSourceSpan = transformers.span; |
+ |
+ SourceSpan polymerTransformerSourceSpan; |
+ SourceSpan entryPointsSourceSpan; |
+ for (var e in transformers) { |
+ if (e == 'polymer') { |
+ // If they had an empty polymer transformer, just get rid of it (we will |
+ // replace it with our own map style one). |
+ var polymerRegex = new RegExp(r'\n\s*-\spolymer\s*'); |
+ // Insert right after the newline. |
+ insertionPoint = pubspecText.indexOf(polymerRegex) + 1; |
+ pubspecText = pubspecText.replaceFirst(polymerRegex, '\n'); |
+ } else if (e is YamlMap && e['polymer'] != null) { |
+ polymerTransformerSourceSpan = e['polymer'].span; |
+ |
+ var existing = e['polymer']['entry_points']; |
+ if (existing == null && e['polymer'].containsKey('entry_points')) { |
+ if (path.split(entryPoint)[0] != 'web') { |
+ print('WARNING: Did not add entry_point $entryPoint to pubspec.yaml' |
+ ' because of existing empty `entry_points` field in polymer' |
+ ' transformer. This defaults to treating all files under `web/`' |
+ ' as entry points, but you tried to add an entry point outside' |
+ ' of the `web/` folder. You will need to explicitly list all' |
+ ' entrypoints that you care about into your pubspec in order to' |
+ ' include any outside of `web/`.'); |
+ } |
+ return false; |
+ } |
+ entryPoints = (existing == null |
+ ? [] |
+ : (existing is String ? [existing] : existing.toList())); |
+ |
+ if (entryPoints.contains(entryPoint)) return false; |
+ entryPoints.add(entryPoint); |
+ |
+ if (existing != null) { |
+ entryPointsSourceSpan = existing.span; |
+ } |
+ } |
+ } |
+ |
+ if (polymerTransformerSourceSpan == null) { |
+ if (insertionPoint == null) { |
+ insertionPoint = transformersSourceSpan.start.offset; |
+ } |
+ textToInsert = '- polymer:\n entry_points:\n'; |
+ } else if (entryPointsSourceSpan == null) { |
+ insertionPoint = polymerTransformerSourceSpan.start.offset; |
+ textToInsert = ' entry_points:\n'; |
+ } else { |
+ insertionPoint = entryPointsSourceSpan.start.offset; |
+ pubspecText = '${pubspecText.substring(0, insertionPoint)}' |
+ '${pubspecText.substring(entryPointsSourceSpan.end.offset)}'; |
+ } |
+ } else { |
+ // There were no transformers at all. |
+ insertionPoint = pubspecText.length; |
+ var optionalNewline = pubspecText.endsWith('\n') ? '' : '\n'; |
+ textToInsert = ''' |
+${optionalNewline}transformers: |
+- polymer: |
+ entry_points: |
+'''; |
+ entryPoints = [entryPoint]; |
+ } |
+ |
+ if (entryPoints == null) entryPoints = [entryPoint]; |
+ // TODO(dgrove): Once dartbug.com/20409 is addressed, use that here. |
+ var entryPointsText = entryPoints.map((e) => ' - $e').join('\n'); |
+ |
+ textToInsert += entryPointsText; |
+ if (insertionPoint == pubspecText.length) { |
+ pubspecText = '${pubspecText}${textToInsert}'; |
+ } else { |
+ pubspecText = '${pubspecText.substring(0, insertionPoint)}' |
+ '${textToInsert}\n${pubspecText.substring(insertionPoint)}'; |
+ } |
+ |
+ _writePubspec(pubspecPath, pubspecText); |
+ return true; |
+} |
+ |
+_writePubspec(String pubspecPath, String text) { |
+ new File(pubspecPath).writeAsStringSync(text); |
+} |