Jonatan Nilsson
f008af597d
Some checks failed
continuous-integration/appveyor/branch AppVeyor build failed
170 lines
No EOL
5.2 KiB
JavaScript
170 lines
No EOL
5.2 KiB
JavaScript
import { EventEmitter } from 'events'
|
|
import fs from 'fs/promises'
|
|
|
|
export default class Application extends EventEmitter {
|
|
constructor(util, db, provider, name, opts = {}) {
|
|
super()
|
|
this.util = util
|
|
this.db = db
|
|
this.config = db.config[name]
|
|
this.provider = provider
|
|
this.name = name
|
|
this.updating = false
|
|
|
|
Object.assign(this, {
|
|
setInterval: opts.setInterval || setInterval,
|
|
fs: opts.fs || fs,
|
|
})
|
|
|
|
this.db.addApplication(name)
|
|
}
|
|
|
|
startAutoupdater() {
|
|
let timer = this.setInterval(() => {
|
|
this.update().then(
|
|
() => {
|
|
this.db.data.core[this.name].updater += 'Automatic update finished successfully. '
|
|
},
|
|
(err) => {
|
|
this.db.data.core[this.name].updater += 'Error while running automatic update: ' + err.message + '. '
|
|
}
|
|
)
|
|
}, (this.config.updateEvery || 180) * 60 * 1000)
|
|
timer.unref()
|
|
}
|
|
|
|
updateLog(message) {
|
|
this.db.data.core[this.name].updater += message
|
|
this.db.log.info(message)
|
|
return message
|
|
}
|
|
|
|
async update() {
|
|
if (this.updating) return
|
|
|
|
this.updating = true
|
|
this.db.data.core[this.name].updater = ''
|
|
let cleanup = true
|
|
let folder = ''
|
|
let log = ''
|
|
let latest = null
|
|
|
|
try {
|
|
log += this.updateLog(`Checking for latest version at ${new Date().toISOString().replace('T', ' ').split('.')[0]}. `) + '\n'
|
|
|
|
latest = await this.provider.getLatestVersion()
|
|
|
|
log += this.updateLog(`Found ${latest.version}. `) + '\n'
|
|
|
|
if (this.db.data.core[this.name].latestInstalled === latest.version) {
|
|
this.updateLog('Already up to date, nothing to do. ')
|
|
this.updating = false
|
|
return
|
|
}
|
|
|
|
latest.id = latest.version
|
|
var found = this.db.get(this.db.data.core[this.name].versions, latest.id)
|
|
if (found) {
|
|
Object.keys(latest).forEach(function(key) {
|
|
found[key] = latest[key]
|
|
})
|
|
latest = found
|
|
log = latest.log + log
|
|
} else {
|
|
this.db.upsert(this.db.data.core[this.name].versions, latest)
|
|
}
|
|
|
|
if (latest.failtodownload && latest.failtodownload > 3) {
|
|
this.updateLog('Version failed to download too many times, skipping this version. ')
|
|
this.updating = false
|
|
return
|
|
}
|
|
if (latest.failtoinstall && latest.failtoinstall > 3) {
|
|
this.updateLog('Version failed to install too many times, skipping this version. ')
|
|
this.updating = false
|
|
return
|
|
}
|
|
|
|
let target = this.util.getPathFromRoot(`./${this.name}/${latest.version}/file${this.util.getExtension(latest.filename)}`)
|
|
folder = this.util.getPathFromRoot(`./${this.name}/${latest.version}`)
|
|
|
|
await this.fs.mkdir(folder, { recursive: true })
|
|
|
|
log += this.updateLog(`Downloading ${latest.link} to ${target}. `) + '\n'
|
|
await this.provider.downloadVersion(latest, target)
|
|
.catch(function(err) {
|
|
latest.failtodownload = (latest.failtodownload || 0) + 1
|
|
return Promise.reject(err)
|
|
})
|
|
|
|
log += '\n' + this.updateLog(`Extracting ${target}. `) + '\n'
|
|
await this.util.extractFile(target, function(msg) {
|
|
log += msg
|
|
}).catch(function(err) {
|
|
latest.failtodownload = (latest.failtodownload || 0) + 1
|
|
return Promise.reject(err)
|
|
})
|
|
|
|
if (!log.endsWith('\n')) {
|
|
log += '\n'
|
|
}
|
|
if (!log.endsWith('\n\n')) {
|
|
log += '\n'
|
|
}
|
|
|
|
await this.fs.stat(this.util.getPathFromRoot(`./${this.name}/${latest.version}/index.mjs`))
|
|
.catch((err) => {
|
|
latest.failtodownload = (latest.failtodownload || 0) + 1
|
|
log += this.updateLog('Version did not include or was missing index.mjs. ') + '\n'
|
|
return Promise.reject(err)
|
|
})
|
|
|
|
cleanup = false
|
|
|
|
let packageStat = await this.fs.stat(this.util.getPathFromRoot(`./${this.name}/${latest.version}/package.json`))
|
|
.catch(function() { return null })
|
|
|
|
if (packageStat) {
|
|
log += this.updateLog(`running npm install --production. `) + '\n'
|
|
await this.util.runCommand(
|
|
'npm.cmd',
|
|
['install', '--production', '--no-optional', '--no-package-lock', '--no-audit', '--loglevel=notice'],
|
|
folder,
|
|
function(msg) {
|
|
log += msg
|
|
}
|
|
).catch(function(err) {
|
|
latest.failtoinstall = (latest.failtoinstall || 0) + 1
|
|
return Promise.reject(err)
|
|
})
|
|
|
|
if (!log.endsWith('\n')) {
|
|
log += '\n'
|
|
}
|
|
if (!log.endsWith('\n\n')) {
|
|
log += '\n'
|
|
}
|
|
|
|
} else {
|
|
log += this.updateLog('Release did not contain package.json, skipping npm install. ') + '\n'
|
|
}
|
|
} catch (err) {
|
|
this.updating = false
|
|
log += this.updateLog(`Error: ${err.message}. `) + '\n'
|
|
if (folder && cleanup) {
|
|
await this.fs.rm(folder, { force: true, recursive: true }).catch((err) => {
|
|
this.updateLog(`Error while cleaning up: ${err.message}. `)
|
|
})
|
|
}
|
|
if (latest) {
|
|
latest.log = log
|
|
}
|
|
return Promise.reject(err)
|
|
}
|
|
|
|
log += this.updateLog(`Finished updating ${this.name} to version ${latest.version}.`) + '\n'
|
|
this.db.data.core[this.name].latestInstalled = latest.version
|
|
latest.log = log
|
|
this.updating = false
|
|
}
|
|
} |