OLD | NEW |
(Empty) | |
| 1 // Copyright (c) 2013, 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 /// **Note**: If you already have a `build.dart` in your application, we |
| 6 /// recommend to use the `package:polymer/builder.dart` library instead. |
| 7 |
| 8 /// Temporary deploy command used to create a version of the app that can be |
| 9 /// compiled with dart2js and deployed. Following pub layout conventions, this |
| 10 /// script will treat any HTML file under a package 'web/' and 'test/' |
| 11 /// directories as entry points. |
| 12 /// |
| 13 /// From an application package you can run deploy by creating a small program |
| 14 /// as follows: |
| 15 /// |
| 16 /// import "package:polymer/deploy.dart" as deploy; |
| 17 /// main() => deploy.main(); |
| 18 /// |
| 19 /// This library should go away once `pub deploy` can be configured to run |
| 20 /// barback transformers. |
| 21 library polymer.deploy; |
| 22 |
| 23 import 'dart:io'; |
| 24 |
| 25 import 'package:args/args.dart'; |
| 26 import 'package:code_transformers/tests.dart' show testingDartSdkDirectory; |
| 27 import 'package:path/path.dart' as path; |
| 28 |
| 29 import 'src/build/common.dart' show TransformOptions, LintOptions, |
| 30 phasesForPolymer; |
| 31 import 'src/build/runner.dart'; |
| 32 import 'transformer.dart'; |
| 33 |
| 34 main(List<String> arguments) { |
| 35 var args = _parseArgs(arguments); |
| 36 if (args == null) exit(1); |
| 37 |
| 38 var test = args['test']; |
| 39 var outDir = args['out']; |
| 40 var filters = []; |
| 41 if (args['file-filter'] != null) { |
| 42 filters = args['file-filter'].split(','); |
| 43 } |
| 44 |
| 45 var options; |
| 46 if (test == null) { |
| 47 var transformOps = new TransformOptions( |
| 48 directlyIncludeJS: args['js'], |
| 49 contentSecurityPolicy: args['csp'], |
| 50 releaseMode: !args['debug']); |
| 51 var phases = createDeployPhases(transformOps); |
| 52 options = new BarbackOptions(phases, outDir, |
| 53 // TODO(sigmund): include here also smoke transformer when it's on by |
| 54 // default. |
| 55 packagePhases: {'polymer': phasesForPolymer}); |
| 56 } else { |
| 57 options = _createTestOptions( |
| 58 test, outDir, args['js'], args['csp'], !args['debug'], |
| 59 filters); |
| 60 } |
| 61 if (options == null) exit(1); |
| 62 |
| 63 print('polymer/deploy.dart: creating a deploy target for ' |
| 64 '"${options.currentPackage}"'); |
| 65 |
| 66 runBarback(options) |
| 67 .then((_) => print('Done! All files written to "$outDir"')) |
| 68 .catchError(_reportErrorAndExit); |
| 69 } |
| 70 |
| 71 BarbackOptions _createTestOptions(String testFile, String outDir, |
| 72 bool directlyIncludeJS, bool contentSecurityPolicy, bool releaseMode, |
| 73 List<String> filters) { |
| 74 |
| 75 var testDir = path.normalize(path.dirname(testFile)); |
| 76 |
| 77 // A test must be allowed to import things in the package. |
| 78 // So we must find its package root, given the entry point. We can do this |
| 79 // by walking up to find pubspec.yaml. |
| 80 var pubspecDir = _findDirWithFile(path.absolute(testDir), 'pubspec.yaml'); |
| 81 if (pubspecDir == null) { |
| 82 print('error: pubspec.yaml file not found, please run this script from ' |
| 83 'your package root directory or a subdirectory.'); |
| 84 return null; |
| 85 } |
| 86 var packageName = readCurrentPackageFromPubspec(pubspecDir); |
| 87 |
| 88 // Find the dart-root so we can include all package dependencies and |
| 89 // transformers from other packages. |
| 90 var pkgDir = path.join(_findDirWithDir(path.absolute(testDir), 'pkg'), 'pkg'); |
| 91 |
| 92 var phases = createDeployPhases(new TransformOptions( |
| 93 entryPoints: [path.relative(testFile, from: pubspecDir)], |
| 94 directlyIncludeJS: directlyIncludeJS, |
| 95 contentSecurityPolicy: contentSecurityPolicy, |
| 96 releaseMode: releaseMode, |
| 97 lint: new LintOptions.disabled()), sdkDir: testingDartSdkDirectory); |
| 98 var dirs = {}; |
| 99 // Note: we include all packages in pkg/ to keep things simple. Ideally this |
| 100 // should be restricted to the transitive dependencies of this package. |
| 101 _subDirs(pkgDir).forEach((p) { dirs[path.basename(p)] = p; }); |
| 102 // Note: packageName may be a duplicate of 'polymer', but that's ok (they |
| 103 // should be the same value). |
| 104 dirs[packageName]= pubspecDir; |
| 105 return new BarbackOptions(phases, outDir, |
| 106 currentPackage: packageName, |
| 107 packageDirs: dirs, |
| 108 // TODO(sigmund): include here also smoke transformer when it's on by |
| 109 // default. |
| 110 packagePhases: {'polymer': phasesForPolymer}, |
| 111 transformTests: true, |
| 112 fileFilter: filters); |
| 113 } |
| 114 |
| 115 String _findDirWithFile(String dir, String filename) { |
| 116 while (!new File(path.join(dir, filename)).existsSync()) { |
| 117 var parentDir = path.dirname(dir); |
| 118 // If we reached root and failed to find it, bail. |
| 119 if (parentDir == dir) return null; |
| 120 dir = parentDir; |
| 121 } |
| 122 return dir; |
| 123 } |
| 124 |
| 125 String _findDirWithDir(String dir, String subdir) { |
| 126 while (!new Directory(path.join(dir, subdir)).existsSync()) { |
| 127 var parentDir = path.dirname(dir); |
| 128 // If we reached root and failed to find it, bail. |
| 129 if (parentDir == dir) return null; |
| 130 dir = parentDir; |
| 131 } |
| 132 return dir; |
| 133 } |
| 134 |
| 135 List<String> _subDirs(String dir) => |
| 136 new Directory(dir).listSync(followLinks: false) |
| 137 .where((d) => d is Directory).map((d) => d.path).toList(); |
| 138 |
| 139 void _reportErrorAndExit(e, trace) { |
| 140 print('Uncaught error: $e'); |
| 141 if (trace != null) print(trace); |
| 142 exit(1); |
| 143 } |
| 144 |
| 145 ArgResults _parseArgs(arguments) { |
| 146 var parser = new ArgParser() |
| 147 ..addFlag('help', abbr: 'h', help: 'Displays this help message.', |
| 148 defaultsTo: false, negatable: false) |
| 149 ..addOption('out', abbr: 'o', help: 'Directory to generate files into.', |
| 150 defaultsTo: 'out') |
| 151 ..addOption('file-filter', help: 'Do not copy in files that match \n' |
| 152 'these filters to the deployed folder, e.g., ".svn"', |
| 153 defaultsTo: null) |
| 154 ..addOption('test', help: 'Deploy the test at the given path.\n' |
| 155 'Note: currently this will deploy all tests in its directory,\n' |
| 156 'but it will eventually deploy only the specified test.') |
| 157 ..addFlag('js', help: |
| 158 'deploy replaces *.dart scripts with *.dart.js. This flag \n' |
| 159 'leaves "packages/browser/dart.js" to do the replacement at runtime.', |
| 160 defaultsTo: true) |
| 161 ..addFlag('debug', help: |
| 162 'run in debug mode. For example, use the debug polyfill \n' |
| 163 'web_components/webcomponents.js instead of the minified one.\n', |
| 164 defaultsTo: false) |
| 165 ..addFlag('csp', help: |
| 166 'extracts inlined JavaScript code to comply with \n' |
| 167 'Content Security Policy restrictions.'); |
| 168 try { |
| 169 var results = parser.parse(arguments); |
| 170 if (results['help']) { |
| 171 _showUsage(parser); |
| 172 return null; |
| 173 } |
| 174 return results; |
| 175 } on FormatException catch (e) { |
| 176 print(e.message); |
| 177 _showUsage(parser); |
| 178 return null; |
| 179 } |
| 180 } |
| 181 |
| 182 _showUsage(parser) { |
| 183 print('Usage: dart --package-root=packages/ ' |
| 184 'package:polymer/deploy.dart [options]'); |
| 185 print(parser.getUsage()); |
| 186 } |
OLD | NEW |