]>
Commit | Line | Data |
---|---|---|
ae510306 SR |
1 | #!/usr/bin/env node |
2 | ||
3 | var path = require('path'); | |
4 | var program = require('commander'); | |
5 | var fs = require('fs'); | |
6 | var fse = require('fs-extra'); | |
ae510306 | 7 | |
6cae7b58 | 8 | const SUPPORTED_FORMATS = new Set(['amd', 'commonjs', 'systemjs', 'umd']); |
ae510306 SR |
9 | |
10 | program | |
6cae7b58 SR |
11 | .option('--as [format]', `output files using various import formats instead of ES6 import and export. Supports ${Array.from(SUPPORTED_FORMATS)}.`) |
12 | .option('-m, --with-source-maps [type]', 'output source maps when not generating a bundled app (type may be empty for external source maps, inline for inline source maps, or both) ') | |
13 | .option('--with-app', 'process app files as well as core files') | |
ae510306 SR |
14 | .parse(process.argv); |
15 | ||
16 | // the various important paths | |
6cae7b58 | 17 | var main_path = path.resolve(__dirname, '..'); |
ae510306 SR |
18 | var core_path = path.resolve(__dirname, '..', 'core'); |
19 | var app_path = path.resolve(__dirname, '..', 'app'); | |
6cae7b58 | 20 | var vendor_path = path.resolve(__dirname, '..', 'vendor'); |
ae510306 SR |
21 | var out_dir_base = path.resolve(__dirname, '..', 'build'); |
22 | var lib_dir_base = path.resolve(__dirname, '..', 'lib'); | |
23 | ||
6cae7b58 SR |
24 | // walkDir *recursively* walks directories trees, |
25 | // calling the callback for all normal files found. | |
26 | var walkDir = function (base_path, cb) { | |
27 | fs.readdir(base_path, (err, files) => { | |
28 | if (err) throw err; | |
ae510306 | 29 | |
6cae7b58 SR |
30 | files.map((filename) => path.join(base_path, filename)).forEach((filepath) => { |
31 | fs.lstat(filepath, (err, stats) => { | |
32 | if (err) throw err; | |
ae510306 | 33 | |
6cae7b58 SR |
34 | if (stats.isSymbolicLink()) return; |
35 | if (stats.isFile()) cb(filepath); | |
36 | if (stats.isDirectory()) walkDir(filepath, cb); | |
ae510306 SR |
37 | }); |
38 | }); | |
39 | }); | |
6cae7b58 | 40 | }; |
ae510306 | 41 | |
6cae7b58 | 42 | var transform_html = function (new_script) { |
ae510306 SR |
43 | // write out the modified vnc.html file that works with the bundle |
44 | var src_html_path = path.resolve(__dirname, '..', 'vnc.html'); | |
45 | var out_html_path = path.resolve(out_dir_base, 'vnc.html'); | |
6cae7b58 | 46 | fs.readFile(src_html_path, (err, contents_raw) => { |
ae510306 SR |
47 | if (err) { throw err; } |
48 | ||
49 | var contents = contents_raw.toString(); | |
ae510306 SR |
50 | |
51 | var start_marker = '<!-- begin scripts -->\n'; | |
52 | var end_marker = '<!-- end scripts -->'; | |
53 | var start_ind = contents.indexOf(start_marker) + start_marker.length; | |
54 | var end_ind = contents.indexOf(end_marker, start_ind); | |
55 | ||
6cae7b58 | 56 | contents = contents.slice(0, start_ind) + `${new_script}\n` + contents.slice(end_ind); |
ae510306 | 57 | |
6cae7b58 | 58 | console.log(`Writing ${out_html_path}`); |
ae510306 SR |
59 | fs.writeFile(out_html_path, contents, function (err) { |
60 | if (err) { throw err; } | |
ae510306 SR |
61 | }); |
62 | }); | |
6cae7b58 | 63 | } |
ae510306 | 64 | |
6cae7b58 SR |
65 | var make_lib_files = function (import_format, source_maps, with_app_dir) { |
66 | if (!import_format) { | |
67 | throw new Error("you must specify an import format to generate compiled noVNC libraries"); | |
68 | } else if (!SUPPORTED_FORMATS.has(import_format)) { | |
69 | throw new Error(`unsupported output format "${import_format}" for import/export -- only ${Array.from(SUPPORTED_FORMATS)} are supported`); | |
70 | } | |
71 | ||
72 | // NB: we need to make a copy of babel_opts, since babel sets some defaults on it | |
73 | const babel_opts = () => ({ | |
74 | plugins: [`transform-es2015-modules-${import_format}`], | |
75 | ast: false, | |
76 | sourceMaps: source_maps, | |
77 | }); | |
78 | const babel = require('babel-core'); | |
79 | ||
80 | var in_path; | |
81 | if (with_app_dir) { | |
82 | var out_path_base = out_dir_base; | |
83 | in_path = main_path; | |
84 | } else { | |
85 | var out_path_base = lib_dir_base; | |
86 | } | |
87 | ||
88 | fse.ensureDirSync(out_path_base); | |
89 | ||
90 | const helpers = require('./use_require_helpers'); | |
91 | const helper = helpers[import_format]; | |
92 | ||
93 | var handleDir = (js_only, in_path_base, filename) => { | |
94 | const out_path = path.join(out_path_base, path.relative(in_path_base, filename)); | |
95 | if(path.extname(filename) !== '.js') { | |
96 | if (!js_only) { | |
97 | console.log(`Writing ${out_path}`); | |
98 | fse.copy(filename, out_path, (err) => { if (err) throw err; }); | |
ae510306 | 99 | } |
6cae7b58 | 100 | return; // skip non-javascript files |
ae510306 | 101 | } |
ae510306 | 102 | |
6cae7b58 SR |
103 | fse.ensureDir(path.dirname(out_path), () => { |
104 | const opts = babel_opts(); | |
105 | if (helper && helpers.optionsOverride) { | |
106 | helper.optionsOverride(opts); | |
107 | } | |
108 | babel.transformFile(filename, babel_opts(), (err, res) => { | |
109 | console.log(`Writing ${out_path}`); | |
110 | if (err) throw err; | |
111 | var {code, map, ast} = res; | |
112 | if (source_maps === true) { | |
113 | // append URL for external source map | |
114 | code += `\n//# sourceMappingURL=${path.basename(out_path)}.map\n`; | |
115 | } | |
116 | fs.writeFile(out_path, code, (err) => { if (err) throw err; }); | |
117 | if (source_maps === true || source_maps === 'both') { | |
118 | console.log(` and ${out_path}.map`); | |
119 | fs.writeFile(`${out_path}.map`, JSON.stringify(map), (err) => { if (err) throw err; }); | |
120 | } | |
121 | }); | |
122 | }); | |
123 | }; | |
124 | ||
125 | walkDir(core_path, handleDir.bind(null, true, in_path || core_path)); | |
126 | walkDir(vendor_path, handleDir.bind(null, true, in_path || main_path)); | |
127 | ||
128 | if (with_app_dir) { | |
129 | walkDir(app_path, handleDir.bind(null, false, in_path || app_path)); | |
130 | ||
131 | const out_app_path = path.join(out_path_base, 'app.js'); | |
132 | if (helper && helper.appWriter) { | |
133 | console.log(`Writing ${out_app_path}`); | |
134 | let out_script = helper.appWriter(out_path_base, out_app_path); | |
135 | transform_html(out_script); | |
136 | } else { | |
137 | console.error(`Unable to generate app for the ${import_format} format!`); | |
138 | } | |
139 | } | |
ae510306 SR |
140 | }; |
141 | ||
6cae7b58 | 142 | make_lib_files(program.as, program.withSourceMaps, program.withApp); |