'use strict'
const fs = require('fs')
const path = require('path')
/**
* Affiche les entités demandées
* @param {string} updateNum Le numéro de l'update
* @param {errorCallback} done
*/
function applyUpdate (updateNum, done) {
// vire notre fichier de lock avant de sortir
function unlockAndQuit (error) {
console.log(`FIN update n°${updateNum} ${error ? 'KO' : 'OK'} `)
if (fs.existsSync(lockFile)) {
try {
fs.unlinkSync(lockFile)
} catch (error) {
console.error(error)
}
}
done(error)
}
if (arguments.length !== 2) throw new Error('Erreur interne, il faut deux arguments')
if (typeof done !== 'function') throw new Error('Erreur interne, pas de callback de commande')
// on est en cli, on override la fct log.error qui écrit dans un log pour le sortir en console à la place
log.error = function logErrorConsole (msg, obj2dump) {
console.error(msg)
if (obj2dump) console.error(obj2dump)
}
const updateFile = path.join(__dirname, 'updates', updateNum + '.js')
const lockFile = path.join(__dirname, '../../../_private/updates.lock')
if (fs.existsSync(lockFile)) return done(new Error(`${lockFile} présent, on ne peut pas lancer ${updateFile}`))
// on le crée (en mettant dedans l'update qu'on va appliquer)
else fs.appendFileSync(lockFile, updateFile)
try {
const update = require(updateFile)
if (!update.run) return unlockAndQuit(new Error(`Le module js ${updateFile} ne contient pas de méthode run`))
console.log(`lancement de l’update n°${updateNum}`)
update.run(unlockAndQuit)
} catch (error) {
unlockAndQuit(error)
}
}
applyUpdate.help = function applyUpdateHelp () {
console.log('La commande applyUpdate demande 1 argument, le n° de l’update à lancer.')
console.log('Ça laissera intact le n° de version de la base)')
}
/**
* Liste les updates disponibles
* @param {errorCallback} done
*/
function listUpdates (done) {
if (typeof done !== 'function') throw new Error('Erreur interne, pas de callback de commande')
const updateDir = path.join(__dirname, 'updates')
if (!fs.existsSync(updateDir)) return done(new Error(`${updateDir} n’existe pas`))
try {
fs.readdir(updateDir, function (error, files) {
if (error) return done(error)
files.forEach((file) => {
if (file.substr(-3) !== '.js') return
const update = require(path.join(updateDir, file))
if (!update || !update.name || !update.run) console.log(`${file} est dans ${updateDir} mais ce n’est pas un update`, update)
else console.log(`${file}\t${update.name} ${update.description ? '\n' + update.description + '\n' : ''}`)
})
console.log('fin listUpdates')
done()
})
} catch (error) {
done(error)
}
}
listUpdates.help = function listUpdatesHelp () {
console.log('La commande listUpdates ne prend pas d’arguments, elle liste les updates disponibles')
}
/**
* Service de gestion des updates via cli
* @service $update-cli
*/
module.exports = function (component) {
component.service('$update-cli', function () {
return {
commands: () => ({
applyUpdate,
listUpdates
})
}
})
}