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' | |
30 show TransformOptions, LintOptions, 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'], filters); | |
59 } | |
60 if (options == null) exit(1); | |
61 | |
62 print('polymer/deploy.dart: creating a deploy target for ' | |
63 '"${options.currentPackage}"'); | |
64 | |
65 runBarback(options) | |
66 .then((_) => print('Done! All files written to "$outDir"')) | |
67 .catchError(_reportErrorAndExit); | |
68 } | |
69 | |
70 BarbackOptions _createTestOptions(String testFile, String outDir, | |
71 bool directlyIncludeJS, bool contentSecurityPolicy, bool releaseMode, | |
72 List<String> filters) { | |
73 var testDir = path.normalize(path.dirname(testFile)); | |
74 | |
75 // A test must be allowed to import things in the package. | |
76 // So we must find its package root, given the entry point. We can do this | |
77 // by walking up to find pubspec.yaml. | |
78 var pubspecDir = _findDirWithFile(path.absolute(testDir), 'pubspec.yaml'); | |
79 if (pubspecDir == null) { | |
80 print('error: pubspec.yaml file not found, please run this script from ' | |
81 'your package root directory or a subdirectory.'); | |
82 return null; | |
83 } | |
84 var packageName = readCurrentPackageFromPubspec(pubspecDir); | |
85 | |
86 // Find the dart-root so we can include all package dependencies and | |
87 // transformers from other packages. | |
88 var pkgDir = path.join(_findDirWithDir(path.absolute(testDir), 'pkg'), 'pkg'); | |
89 | |
90 var phases = createDeployPhases(new TransformOptions( | |
91 entryPoints: [path.relative(testFile, from: pubspecDir)], | |
92 directlyIncludeJS: directlyIncludeJS, | |
93 contentSecurityPolicy: contentSecurityPolicy, | |
94 releaseMode: releaseMode, | |
95 lint: new LintOptions.disabled()), sdkDir: testingDartSdkDirectory); | |
96 var dirs = {}; | |
97 // Note: we include all packages in pkg/ to keep things simple. Ideally this | |
98 // should be restricted to the transitive dependencies of this package. | |
99 _subDirs(pkgDir).forEach((p) { | |
100 dirs[path.basename(p)] = p; | |
101 }); | |
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, packageDirs: dirs, | |
107 // TODO(sigmund): include here also smoke transformer when it's on by | |
108 // default. | |
109 packagePhases: {'polymer': phasesForPolymer}, | |
110 transformTests: true, | |
111 fileFilter: filters); | |
112 } | |
113 | |
114 String _findDirWithFile(String dir, String filename) { | |
115 while (!new File(path.join(dir, filename)).existsSync()) { | |
116 var parentDir = path.dirname(dir); | |
117 // If we reached root and failed to find it, bail. | |
118 if (parentDir == dir) return null; | |
119 dir = parentDir; | |
120 } | |
121 return dir; | |
122 } | |
123 | |
124 String _findDirWithDir(String dir, String subdir) { | |
125 while (!new Directory(path.join(dir, subdir)).existsSync()) { | |
126 var parentDir = path.dirname(dir); | |
127 // If we reached root and failed to find it, bail. | |
128 if (parentDir == dir) return null; | |
129 dir = parentDir; | |
130 } | |
131 return dir; | |
132 } | |
133 | |
134 List<String> _subDirs(String dir) => new Directory(dir) | |
135 .listSync(followLinks: false) | |
136 .where((d) => d is Directory) | |
137 .map((d) => d.path) | |
138 .toList(); | |
139 | |
140 void _reportErrorAndExit(e, trace) { | |
141 print('Uncaught error: $e'); | |
142 if (trace != null) print(trace); | |
143 exit(1); | |
144 } | |
145 | |
146 ArgResults _parseArgs(arguments) { | |
147 var parser = new ArgParser() | |
148 ..addFlag('help', | |
149 abbr: 'h', | |
150 help: 'Displays this help message.', | |
151 defaultsTo: false, | |
152 negatable: false) | |
153 ..addOption('out', | |
154 abbr: 'o', help: 'Directory to generate files into.', defaultsTo: 'out') | |
155 ..addOption('file-filter', help: 'Do not copy in files that match \n' | |
156 'these filters to the deployed folder, e.g., ".svn"', defaultsTo: null) | |
157 ..addOption('test', help: 'Deploy the test at the given path.\n' | |
158 'Note: currently this will deploy all tests in its directory,\n' | |
159 'but it will eventually deploy only the specified test.') | |
160 ..addFlag('js', | |
161 help: 'deploy replaces *.dart scripts with *.dart.js. This flag \n' | |
162 'leaves "packages/browser/dart.js" to do the replacement at runtime.', | |
163 defaultsTo: true) | |
164 ..addFlag('debug', | |
165 help: 'run in debug mode. For example, use the debug polyfill \n' | |
166 'web_components/webcomponents.js instead of the minified one.\n', | |
167 defaultsTo: false) | |
168 ..addFlag('csp', help: 'extracts inlined JavaScript code to comply with \n' | |
169 'Content Security Policy restrictions.'); | |
170 try { | |
171 var results = parser.parse(arguments); | |
172 if (results['help']) { | |
173 _showUsage(parser); | |
174 return null; | |
175 } | |
176 return results; | |
177 } on FormatException catch (e) { | |
178 print(e.message); | |
179 _showUsage(parser); | |
180 return null; | |
181 } | |
182 } | |
183 | |
184 _showUsage(parser) { | |
185 print('Usage: dart --package-root=packages/ ' | |
186 'package:polymer/deploy.dart [options]'); | |
187 print(parser.getUsage()); | |
188 } | |
OLD | NEW |