Created
December 8, 2014 13:56
-
-
Save Qvatra/db825eae720c70c0c88a to your computer and use it in GitHub Desktop.
ionic development: build.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var fs = require('fs'); | |
var path = require('path'); | |
var exec = require('child_process').exec; | |
var archiver = require('archiver'); //npm install archiver | |
var prompt = require('prompt'); //npm install prompt | |
var appVersion; | |
var androidStoreVersion; | |
var device; | |
var mode; | |
var dest; | |
function info() { | |
console.log('usage: >node build <android/ios> <release/debug>'); | |
process.exit(0); | |
} | |
function verifyArg(arg) { | |
if (arg === 'ios' || arg === 'android') { | |
device = (arg === 'ios') ? 'ios' : 'android'; | |
dest = (device === 'ios') ? '../iosBuild' : '../androidBuild'; | |
} else if (arg === 'release' || arg === 'debug') { | |
mode = (arg === 'release') ? 'release' : 'debug'; | |
} else { | |
info(); | |
} | |
} | |
function fatalError(err){ | |
console.error('fatal Error: ' + err); | |
process.exit(1); | |
} | |
function setAndroidStoreVersion(callback) { | |
prompt.get(['storeVersion'], function (err, result) { | |
if (!result.storeVersion) { | |
setAndroidStoreVersion(); | |
} else { | |
androidStoreVersion = result.storeVersion; | |
callback(); | |
} | |
}); | |
} | |
function setAppVersion(callback) { | |
prompt.get(['appVersion'], function (err, result) { | |
if (!result.appVersion) { | |
setAppVersion(callback); | |
} else { | |
appVersion = result.appVersion; | |
if (device === 'ios') { | |
callback(); | |
} else { | |
setAndroidStoreVersion(callback); | |
} | |
} | |
}); | |
} | |
function makeZip(from, to, zipName, callback){ | |
var zipArchive = archiver('zip'); | |
var zipOutput = fs.createWriteStream(to+'/'+zipName); | |
zipOutput.on('close', function() { | |
console.log('zipping done: ', to+'/'+zipName); | |
callback(); | |
}); | |
zipArchive.pipe(zipOutput); | |
zipArchive.bulk([{ src: [ '**/*' ], cwd: from, expand: true }]); | |
zipArchive.finalize(function(err, bytes) { | |
if(err) fatalError(err); | |
console.log('done:', base, bytes); | |
}); | |
} | |
function createPathSync(dirPath, mode, fullPath){ //usage: createPathSync('a/b/c/d', [mode]); | |
if (typeof fullPath == 'undefined') fullPath = dirPath; //initialization | |
try{//try to make dir | |
fs.mkdirSync(dirPath, mode); | |
//if succeeded go recursive or finish | |
if (!fs.existsSync(fullPath)) createPathSync(fullPath, mode, fullPath); | |
} catch(err) { | |
createPathSync(path.dirname(dirPath), mode, fullPath); | |
} | |
} | |
function copyFileSync( source, target ) { | |
var targetFile = target; | |
if ( fs.existsSync( target ) ) { | |
if ( fs.lstatSync( target ).isDirectory() ) { | |
targetFile = path.join( target, path.basename( source ) ); | |
} | |
} | |
fs.createReadStream( source ).pipe( fs.createWriteStream( targetFile ) ); | |
} | |
function copyFolderRecursiveSync( source, target ) { | |
var files = []; | |
if ( !fs.existsSync( target ) ) { //assure that target path exists | |
createPathSync(target); | |
} | |
if ( fs.lstatSync( source ).isDirectory() ) { | |
files = fs.readdirSync( source ); | |
files.forEach( function ( file, index ) { | |
var curSource = path.join( source, file ); | |
var curTarget = path.join( target, file ); | |
if ( fs.lstatSync( curSource ).isDirectory() ) { | |
copyFolderRecursiveSync( curSource, curTarget ); | |
} else { | |
copyFileSync( curSource, curTarget ); | |
} | |
} ); | |
} | |
} | |
function deleteFolderRecursiveSync(path) { | |
if( fs.existsSync(path) ) { | |
fs.readdirSync(path).forEach(function(file,index){ | |
var curPath = path + "/" + file; | |
if(fs.lstatSync(curPath).isDirectory()) { | |
deleteFolderRecursiveSync(curPath); | |
} else { // delete file | |
fs.unlinkSync(curPath); | |
} | |
}); | |
fs.rmdirSync(path); | |
} | |
}; | |
//patching config.xml to change index.html to bootstrapper.html | |
function patchConfigXml(){ | |
fs.readFile(dest + '/config.xml', 'utf8', function (err, data) { | |
if (err) fatalError(err);; | |
data = data.replace('index.html', 'bootstrapper.html'); | |
data = data.replace(/ version="....."/g, ' version="' + appVersion + '"'); | |
if (device === 'android'){ | |
data = data.replace(/ android-versionName="....."/g, ' android-versionName="' + appVersion + '"'); | |
var start = data.indexOf('android-versionCode="') + 21; | |
var end = data.indexOf('"', start); | |
data = data.substring(0, start) + androidStoreVersion + data.substr(end); | |
} | |
fs.writeFile(dest + '/config.xml', data, function (err) { | |
if(err) { | |
fatalError(err); | |
} else { | |
console.log("successfully patched!"); | |
} | |
}); | |
}); | |
} | |
function changeDir(target) { | |
try { | |
var dir0 = process.cwd(); | |
process.chdir(target); | |
console.log('change directory: ' + dir0 + ' --> ' + process.cwd()); | |
} catch (err) { | |
fatalError(err); | |
} | |
} | |
function shellExec(cmd, callback){ | |
console.log(cmd + ' executing...'); | |
exec(cmd, function(err, stdout, stderr) { | |
console.log('stdout: ' + stdout); | |
console.log('stderr: ' + stderr); | |
if (err !== null) { | |
fatalError(err); | |
} else { | |
typeof callback === 'function' && callback(); | |
} | |
}); | |
} | |
function start() { | |
//clear | |
deleteFolderRecursiveSync(dest); | |
console.log(dest + ' was cleared'); | |
//some files/folders | |
copyFolderRecursiveSync('bootstrapper', dest + '/www'); | |
console.log('bootstrapper copied to ' + dest + '/www'); | |
copyFolderRecursiveSync('config', dest + '/config'); | |
console.log('config folder copied to ' + dest + '/config'); | |
copyFolderRecursiveSync('hooks', dest + '/hooks'); | |
console.log('hooks folder copied to ' + dest + '/hooks'); | |
copyFileSync('config.xml', dest + '/config.xml'); | |
console.log('config.xml copied to ' + dest + '/config.xml'); | |
patchConfigXml(); | |
if (device === 'android') { | |
//handling android cordova.zip | |
var cordovaDest = dest + '/cordovaZip'; | |
copyFolderRecursiveSync('platforms/android/assets/www/plugins', cordovaDest + '/plugins'); | |
console.log('plugins copied to cordovaZip'); | |
copyFileSync('platforms/android/assets/www/cordova.js', cordovaDest + '/cordova.js'); | |
console.log('cordova.js copied to cordovaZip'); | |
copyFileSync('platforms/android/assets/www/cordova_plugins.js', cordovaDest + '/cordova_plugins.js'); | |
console.log('cordova_plugins.js copied to cordovaZip'); | |
} else if (device === 'ios') { //check the path | |
//handling ios cordova.zip | |
var cordovaDest = dest + '/cordovaZip'; | |
copyFolderRecursiveSync('platforms/ios/assets/www/plugins', cordovaDest + '/plugins'); | |
console.log('plugins copied to cordovaZip'); | |
copyFileSync('platforms/ios/assets/www/cordova.js', cordovaDest + '/cordova.js'); | |
console.log('cordova.js copied to cordovaZip'); | |
copyFileSync('platforms/ios/assets/www/cordova_plugins.js', cordovaDest + '/cordova_plugins.js'); | |
console.log('cordova_plugins.js copied to cordovaZip'); | |
} | |
//handling content.zip | |
var contentDest = dest + '/contentZip'; | |
createPathSync(contentDest); | |
console.log(contentDest + ' created'); | |
copyFileSync('www/content/contentInfo.json', contentDest + '/contentInfo.json'); | |
console.log('contentInfo.json copied to contentZip'); | |
copyFileSync('www/content/search_stoplist.txt', contentDest + '/search_stoplist.txt'); | |
console.log('search_stoplist.txt copied to contentZip'); | |
//handling www.zip | |
var wwwDest = dest + '/wwwZip/www'; | |
if (mode === 'release') { | |
createPathSync(wwwDest + '/js'); | |
copyFileSync('www/js/tslib.js', wwwDest + '/js'); | |
console.log('tslib.js copied to wwwZip/js'); | |
copyFileSync('www/index-min.html', wwwDest + '/index.html'); | |
console.log('index.html copied to wwwZip'); | |
createPathSync(wwwDest + '/template/directives/bookviewer'); | |
copyFileSync('www/template/directives/bookviewer/bookviewer-min.html', wwwDest + '/template/directives/bookviewer/bookviewer.html'); | |
console.log('bookviewer.html copied to /template/directives/bookviewer'); | |
copyFolderRecursiveSync('www/views/min', wwwDest + '/views'); | |
console.log('views copied to wwwZip'); | |
} else { | |
copyFolderRecursiveSync('www/js', wwwDest + '/js'); | |
console.log('js copied to wwwZip'); | |
copyFileSync('www/index.html', wwwDest + '/index.html'); | |
console.log('index.html copied to wwwZip'); | |
copyFolderRecursiveSync('www/template', wwwDest + '/template'); | |
console.log('template copied to wwwZip'); | |
copyFolderRecursiveSync('www/views', wwwDest + '/views'); | |
console.log('views copied to wwwZip'); | |
} | |
copyFolderRecursiveSync('www/images', wwwDest + '/images'); | |
console.log('images copied to wwwZip'); | |
copyFolderRecursiveSync('www/fonts', wwwDest + '/fonts'); | |
console.log('fonts copied to wwwZip'); | |
copyFolderRecursiveSync('www/css', wwwDest + '/css'); | |
console.log('css copied to wwwZip'); | |
copyFileSync('www/404.html', wwwDest + '/404.html'); | |
console.log('404.html copied to wwwZip'); | |
copyFileSync('www/favicon.ico', wwwDest + '/favicon.ico'); | |
console.log('favicon.ico copied to wwwZip'); | |
copyFileSync('www/robots.txt', wwwDest + '/robots.txt'); | |
console.log('robots.txt copied to wwwZip'); | |
copyFileSync('www/touch-icon-ipad.png', wwwDest + '/touch-icon-ipad.png'); | |
console.log('touch-icon-ipad.png copied to wwwZip'); | |
copyFileSync('www/touch-icon-ipad-retina.png', wwwDest + '/touch-icon-ipad-retina.png'); | |
console.log('touch-icon-ipad-retina.png copied to wwwZip'); | |
copyFileSync('www/touch-icon-iphone.png', wwwDest + '/touch-icon-iphone.png'); | |
console.log('touch-icon-iphone.png copied to wwwZip'); | |
copyFileSync('www/touch-icon-iphone-retina.png', wwwDest + '/touch-icon-iphone-retina.png'); | |
console.log('touch-icon-iphone-retina.png copied to wwwZip'); | |
//copy lib files to wwwDest | |
var lib = wwwDest + '/lib'; | |
createPathSync(lib + '/jQuery/dist'); | |
copyFileSync('www/lib/jQuery/dist/jquery.min.js', lib + '/jQuery/dist/jquery.min.js'); | |
console.log('jquery.min.js copied'); | |
createPathSync(lib + '/raygun4js/dist'); | |
copyFileSync('www/lib/raygun4js/dist/raygun.min.js', lib + '/raygun4js/dist/raygun.min.js'); | |
console.log('raygun.min.js copied'); | |
createPathSync(lib + '/handlebars'); | |
copyFileSync('www/lib/handlebars/handlebars.min.js', lib + '/handlebars/handlebars.min.js'); | |
console.log('handlebars.min.js copied'); | |
createPathSync(lib + '/lazy.js'); | |
copyFileSync('www/lib/lazy.js/lazy.js', lib + '/lazy.js/lazy.js'); | |
console.log('lazy.js copied'); | |
createPathSync(lib + '/angular'); | |
copyFileSync('www/lib/angular/angular.min.js', lib + '/angular/angular.min.js'); | |
console.log('angular.min.js copied'); | |
createPathSync(lib + '/angular-animate'); | |
copyFileSync('www/lib/angular-animate/angular-animate.min.js', lib + '/angular-animate/angular-animate.min.js'); | |
console.log('angular-animate.min.js copied'); | |
createPathSync(lib + '/angular-sanitize'); | |
copyFileSync('www/lib/angular-sanitize/angular-sanitize.min.js', lib + '/angular-sanitize/angular-sanitize.min.js'); | |
console.log('angular-sanitize.min.js copied'); | |
createPathSync(lib + '/angular-ui-router/release'); | |
copyFileSync('www/lib/angular-ui-router/release/angular-ui-router.min.js', lib + '/angular-ui-router/release/angular-ui-router.min.js'); | |
console.log('angular-ui-router.min.js copied'); | |
createPathSync(lib + '/collide'); | |
copyFileSync('www/lib/collide/collide.js', lib + '/collide/collide.js'); | |
console.log('collide.js copied'); | |
createPathSync(lib + '/ionic/release/js'); | |
copyFileSync('www/lib/ionic/release/js/ionic.min.js', lib + '/ionic/release/js/ionic.min.js'); | |
copyFileSync('www/lib/ionic/release/js/ionic-angular.min.js', lib + '/ionic/release/js/ionic-angular.min.js'); | |
console.log('ionic.min.js and ionic-angular.min.js copied'); | |
createPathSync(lib + '/lunr.js'); | |
copyFileSync('www/lib/lunr.js/lunr.min.js', lib + '/lunr.js/lunr.min.js'); | |
console.log('lunr.min.js copied'); | |
makeZip(dest + '/cordovaZip', dest + '/www', 'cordova.zip', function () { | |
makeZip(dest + '/contentZip', dest + '/www', 'content.zip', function () { | |
makeZip(dest + '/wwwZip', dest + '/www', 'www.zip', function () { | |
deleteFolderRecursiveSync(dest + '/wwwZip'); | |
console.log('wwwZip removed'); | |
//done with copying; exec commands here | |
if (device === 'android') { | |
shellCommandsAndroid(); | |
} else if (device === 'ios') { | |
shellCommandsIOS(); | |
} | |
}); | |
deleteFolderRecursiveSync(dest + '/contentZip'); | |
console.log('contentZip removed'); | |
}); | |
deleteFolderRecursiveSync(dest + '/cordovaZip'); | |
console.log('cordovaZip removed'); | |
}); | |
} | |
function shellCommandsAndroid(){ | |
changeDir(dest); | |
shellExec('cordova restore plugins --experimental', function(){ | |
shellExec('cordova platform add android', function () { | |
//shellExec('cordova run android'); | |
shellExec('cordova build --release android', function () { | |
shellExec('jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore config/android/elseviernextens.keystore platforms/android/ant-build/CordovaApp-release-unsigned.apk -storepass nextens elseviernextens', function () { | |
shellExec('zipalign -v 4 platforms/android/ant-build/CordovaApp-release-unsigned.apk nextens.apk'); | |
}); | |
}); | |
}); | |
}); | |
} | |
function shellCommandsIOS(){ | |
changeDir(dest); | |
shellExec('cordova restore plugins --experimental', function () { | |
shellExec('cordova platform add ios', function () { | |
//shellExec('cordova run ios'); | |
shellExec('cordova build --release ios', function () { | |
//to do | |
}); | |
}); | |
}); | |
} | |
///------------------------------------------------------------------------------------------------------------------ | |
///---plain---------------------------------------------------------------------------------------------------------- | |
///------------------------------------------------------------------------------------------------------------------ | |
if (process.argv.length === 4) { | |
verifyArg(process.argv[2]); | |
verifyArg(process.argv[3]); | |
} else { | |
info(); | |
} | |
setAppVersion(function () { | |
shellExec('gulp ' + mode, function () { | |
start(); | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment