Files
stf-DeviceFarmer-1/lib/util/bundletool.js
2024-11-29 11:02:11 +01:00

154 lines
4.5 KiB
JavaScript

/**
* Copyright © 2024 contains code contributed by Orange SA, authors: Denis Barbaron - Licensed under the Apache license 2.0
**/
var cp = require('child_process')
var fs = require('fs')
var path = require('path')
var Promise = require('bluebird')
var yauzl = require('yauzl')
var logger = require('./logger')
module.exports = function(options) {
return new Promise(function(resolve, reject) {
var log = logger.createLogger('util:bundletool')
var bundletoolFilePath = options.bundletoolPath
var bundle = options.file
var bundlePath = bundle.path
var outputPath = bundlePath + '.apks'
var keystore = options.keystore
function checkIfJava() {
return new Promise(function(resolve, reject) {
var check = cp.spawn('java', ['-version'])
var stderrChunks = []
check.on('error', function(err) {
reject(err)
})
check.stderr.on('data', function(data) {
stderrChunks = stderrChunks.concat(data)
})
check.stderr.on('end', function() {
var data = Buffer.concat(stderrChunks).toString().split('\n')[0]
var regex = new RegExp('(openjdk|java) version')
var javaVersion = regex.test(data) ? data.split(' ')[2].replace(/"/g, '') : false
if (javaVersion !== false) {
resolve(javaVersion)
}
else {
reject(new Error('Java not found'), null)
}
})
})
}
function convert() {
var proc = cp.spawn('java', [
'-jar'
, bundletoolFilePath
, 'build-apks'
, `--bundle=${bundlePath}`
, `--output=${outputPath}`
, `--ks=${keystore.ksPath}`
, `--ks-pass=pass:${keystore.ksPass}`
, `--ks-key-alias=${keystore.ksKeyAlias}`
, `--key-pass=pass:${keystore.ksKeyPass}`
, '--overwrite'
, '--mode=universal'
])
proc.on('error', function(err) {
reject(err)
})
proc.on('exit', function(code, signal) {
if (signal) {
reject(new Error('Exited with signal ' + signal))
}
else if (code === 0) {
yauzl.open(outputPath, {lazyEntries: true}, function(err, zipfile) {
if (err) {
reject(err)
}
zipfile.readEntry()
zipfile.on('entry', function(entry) {
if (/\/$/.test(entry.fileName)) {
zipfile.readEntry()
}
else {
zipfile.openReadStream(entry, function(err, readStream) {
if (err) {
reject(err)
}
readStream.on('end', function() {
zipfile.readEntry()
})
var writeStream = fs.createWriteStream(path.join('/tmp/', entry.fileName))
writeStream.on('error', function(err) {
reject(err)
})
readStream.pipe(writeStream)
})
}
})
zipfile.on('error', function(err) {
reject(err)
})
zipfile.once('end', function() {
fs.copyFileSync('/tmp/universal.apk', bundlePath)
fs.unlinkSync('/tmp/universal.apk')
fs.unlinkSync('/tmp/toc.pb')
fs.unlinkSync(outputPath)
log.info('AAB -> APK')
resolve(bundle)
})
})
}
else {
reject(new Error('Exited with status ' + code))
}
})
}
if (bundle.isAab === true) {
log.info('AAB detected')
checkIfJava()
.then(function() {
if (!fs.existsSync(keystore.ksPath)) {
cp.spawnSync('keytool', [
'-genkey'
, '-noprompt'
, '-keystore', keystore.ksPath
, '-alias', keystore.ksKeyAlias
, '-keyalg', keystore.ksKeyalg
, '-keysize', keystore.ksKeysize
, '-storepass', keystore.ksPass
, '-keypass', keystore.ksKeyPass
, '-dname', keystore.ksDname
, '-validity', keystore.ksValidity
])
}
})
.then(function() {
if(!fs.existsSync(keystore.ksPath)) {
reject('Keystore not found')
}
else if(!fs.existsSync(bundletoolFilePath)) {
reject('bundletool not found')
}
else {
convert()
}
})
.catch(function(err) {
reject(err)
})
}
else {
resolve(bundle)
}
})
}