2016-09-14 13:52:53 -04:00
#!/usr/bin/env node
var path = require ( 'path' ) ;
var program = require ( 'commander' ) ;
var fs = require ( 'fs' ) ;
var fse = require ( 'fs-extra' ) ;
2017-02-04 17:12:00 -05:00
const SUPPORTED _FORMATS = new Set ( [ 'amd' , 'commonjs' , 'systemjs' , 'umd' ] ) ;
2016-09-14 13:52:53 -04:00
program
2017-02-04 17:12:00 -05:00
. option ( '--as [format]' , ` output files using various import formats instead of ES6 import and export. Supports ${ Array . from ( SUPPORTED _FORMATS ) } . ` )
. 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) ' )
. option ( '--with-app' , 'process app files as well as core files' )
2016-09-14 13:52:53 -04:00
. parse ( process . argv ) ;
// the various important paths
2017-02-04 17:12:00 -05:00
var main _path = path . resolve ( _ _dirname , '..' ) ;
2016-09-14 13:52:53 -04:00
var core _path = path . resolve ( _ _dirname , '..' , 'core' ) ;
var app _path = path . resolve ( _ _dirname , '..' , 'app' ) ;
2017-02-04 17:12:00 -05:00
var vendor _path = path . resolve ( _ _dirname , '..' , 'vendor' ) ;
2016-09-14 13:52:53 -04:00
var out _dir _base = path . resolve ( _ _dirname , '..' , 'build' ) ;
var lib _dir _base = path . resolve ( _ _dirname , '..' , 'lib' ) ;
2017-02-04 17:12:00 -05:00
// walkDir *recursively* walks directories trees,
// calling the callback for all normal files found.
2017-02-11 16:49:03 -05:00
var walkDir = function ( base _path , cb , filter ) {
2017-02-04 17:12:00 -05:00
fs . readdir ( base _path , ( err , files ) => {
if ( err ) throw err ;
2016-09-14 13:52:53 -04:00
2017-02-04 17:12:00 -05:00
files . map ( ( filename ) => path . join ( base _path , filename ) ) . forEach ( ( filepath ) => {
fs . lstat ( filepath , ( err , stats ) => {
if ( err ) throw err ;
2016-09-14 13:52:53 -04:00
2017-02-11 16:49:03 -05:00
if ( filter !== undefined && ! filter ( filepath , stats ) ) return ;
2017-02-04 17:12:00 -05:00
if ( stats . isSymbolicLink ( ) ) return ;
if ( stats . isFile ( ) ) cb ( filepath ) ;
2017-02-11 16:49:03 -05:00
if ( stats . isDirectory ( ) ) walkDir ( filepath , cb , filter ) ;
2016-09-14 13:52:53 -04:00
} ) ;
} ) ;
} ) ;
2017-02-04 17:12:00 -05:00
} ;
2016-09-14 13:52:53 -04:00
2017-02-04 17:12:00 -05:00
var transform _html = function ( new _script ) {
2016-09-14 13:52:53 -04:00
// write out the modified vnc.html file that works with the bundle
var src _html _path = path . resolve ( _ _dirname , '..' , 'vnc.html' ) ;
var out _html _path = path . resolve ( out _dir _base , 'vnc.html' ) ;
2017-02-04 17:12:00 -05:00
fs . readFile ( src _html _path , ( err , contents _raw ) => {
2016-09-14 13:52:53 -04:00
if ( err ) { throw err ; }
var contents = contents _raw . toString ( ) ;
var start _marker = '<!-- begin scripts -->\n' ;
var end _marker = '<!-- end scripts -->' ;
var start _ind = contents . indexOf ( start _marker ) + start _marker . length ;
var end _ind = contents . indexOf ( end _marker , start _ind ) ;
2017-02-04 17:12:00 -05:00
contents = contents . slice ( 0 , start _ind ) + ` ${ new _script } \n ` + contents . slice ( end _ind ) ;
2016-09-14 13:52:53 -04:00
2017-02-04 17:12:00 -05:00
console . log ( ` Writing ${ out _html _path } ` ) ;
2016-09-14 13:52:53 -04:00
fs . writeFile ( out _html _path , contents , function ( err ) {
if ( err ) { throw err ; }
} ) ;
} ) ;
2017-02-04 17:12:00 -05:00
}
2016-09-14 13:52:53 -04:00
2017-02-04 17:12:00 -05:00
var make _lib _files = function ( import _format , source _maps , with _app _dir ) {
if ( ! import _format ) {
throw new Error ( "you must specify an import format to generate compiled noVNC libraries" ) ;
} else if ( ! SUPPORTED _FORMATS . has ( import _format ) ) {
throw new Error ( ` unsupported output format " ${ import _format } " for import/export -- only ${ Array . from ( SUPPORTED _FORMATS ) } are supported ` ) ;
}
// NB: we need to make a copy of babel_opts, since babel sets some defaults on it
const babel _opts = ( ) => ( {
plugins : [ ` transform-es2015-modules- ${ import _format } ` ] ,
ast : false ,
sourceMaps : source _maps ,
} ) ;
const babel = require ( 'babel-core' ) ;
var in _path ;
if ( with _app _dir ) {
var out _path _base = out _dir _base ;
in _path = main _path ;
} else {
var out _path _base = lib _dir _base ;
}
fse . ensureDirSync ( out _path _base ) ;
const helpers = require ( './use_require_helpers' ) ;
const helper = helpers [ import _format ] ;
var handleDir = ( js _only , in _path _base , filename ) => {
const out _path = path . join ( out _path _base , path . relative ( in _path _base , filename ) ) ;
if ( path . extname ( filename ) !== '.js' ) {
if ( ! js _only ) {
console . log ( ` Writing ${ out _path } ` ) ;
fse . copy ( filename , out _path , ( err ) => { if ( err ) throw err ; } ) ;
2016-09-14 13:52:53 -04:00
}
2017-02-04 17:12:00 -05:00
return ; // skip non-javascript files
2016-09-14 13:52:53 -04:00
}
2017-02-04 17:12:00 -05:00
fse . ensureDir ( path . dirname ( out _path ) , ( ) => {
const opts = babel _opts ( ) ;
if ( helper && helpers . optionsOverride ) {
helper . optionsOverride ( opts ) ;
}
babel . transformFile ( filename , babel _opts ( ) , ( err , res ) => {
console . log ( ` Writing ${ out _path } ` ) ;
if ( err ) throw err ;
var { code , map , ast } = res ;
if ( source _maps === true ) {
// append URL for external source map
code += ` \n //# sourceMappingURL= ${ path . basename ( out _path ) } .map \n ` ;
}
fs . writeFile ( out _path , code , ( err ) => { if ( err ) throw err ; } ) ;
if ( source _maps === true || source _maps === 'both' ) {
console . log ( ` and ${ out _path } .map ` ) ;
fs . writeFile ( ` ${ out _path } .map ` , JSON . stringify ( map ) , ( err ) => { if ( err ) throw err ; } ) ;
}
} ) ;
} ) ;
} ;
walkDir ( core _path , handleDir . bind ( null , true , in _path || core _path ) ) ;
2017-02-11 16:49:03 -05:00
walkDir ( vendor _path , handleDir . bind ( null , true , in _path || main _path ) , ( filepath , stats ) => ! ( ( stats . isDirectory ( ) && path . basename ( filepath ) === 'browser-es-module-loader' ) || path . basename ( filepath ) === 'sinon.js' ) ) ;
2017-02-04 17:12:00 -05:00
if ( with _app _dir ) {
walkDir ( app _path , handleDir . bind ( null , false , in _path || app _path ) ) ;
const out _app _path = path . join ( out _path _base , 'app.js' ) ;
if ( helper && helper . appWriter ) {
console . log ( ` Writing ${ out _app _path } ` ) ;
let out _script = helper . appWriter ( out _path _base , out _app _path ) ;
transform _html ( out _script ) ;
} else {
console . error ( ` Unable to generate app for the ${ import _format } format! ` ) ;
}
}
2016-09-14 13:52:53 -04:00
} ;
2017-02-04 17:12:00 -05:00
make _lib _files ( program . as , program . withSourceMaps , program . withApp ) ;