wallet-core/node_modules/hullabaloo-config-manager/lib/Verifier.js
2017-08-14 05:02:09 +02:00

180 lines
5.1 KiB
JavaScript

'use strict'
const fs = require('fs')
const path = require('path')
const isEqual = require('lodash.isequal')
const md5Hex = require('md5-hex')
const SafeBuffer = require('safe-buffer').Buffer
const currentEnv = require('./currentEnv')
const hashDependencies = require('./hashDependencies')
const hashSources = require('./hashSources')
function ensureMissingBabelrcFile (file, cache) {
if (cache && cache.fileExistence && cache.fileExistence.has(file)) {
return cache.fileExistence.get(file)
}
const promise = new Promise((resolve, reject) => {
fs.access(file, err => {
if (err) {
if (err.code !== 'ENOENT') {
reject(err)
} else {
resolve(true)
}
} else {
resolve(false)
}
})
})
if (cache && cache.fileExistence) {
cache.fileExistence.set(file, promise)
}
return promise
}
class Verifier {
constructor (babelrcDir, envNames, dependencies, sources) {
Object.assign(this, { babelrcDir, envNames, dependencies, sources })
}
selectByEnv (arr, envName, mapFn) {
const selectDefault = !this.envNames.has(envName)
return arr
.filter(item => selectDefault ? item.default : item.envs.has(envName))
.map(mapFn || (item => item))
}
cacheKeysForCurrentEnv () {
const envName = currentEnv()
const getHash = item => item.hash
const dependencyHashes = this.selectByEnv(this.dependencies, envName, getHash)
const sourceHashes = this.selectByEnv(this.sources, envName, getHash)
return {
dependencies: md5Hex(dependencyHashes),
sources: md5Hex(sourceHashes)
}
}
verifyCurrentEnv (fixedHashes, cache) {
const envName = currentEnv()
const sourcesToHash = this.selectByEnv(this.sources, envName)
const expectedSourceHashes = sourcesToHash.map(item => item.hash)
const pendingSourceHashes = hashSources(sourcesToHash, fixedHashes && fixedHashes.sources, cache)
let checkedBabelrcFile = true
if (this.babelrcDir) {
const babelrcFile = path.join(this.babelrcDir, '.babelrc')
if (!sourcesToHash.some(item => item.source === babelrcFile)) {
checkedBabelrcFile = ensureMissingBabelrcFile(babelrcFile, cache)
}
}
const dependenciesToHash = this.selectByEnv(this.dependencies, envName)
const expectedDependencyHashes = dependenciesToHash.map(item => item.hash)
const pendingDependencyHashes = hashDependencies(dependenciesToHash, cache)
return Promise.all([
pendingSourceHashes,
checkedBabelrcFile
])
.then(result => {
const sourceHashes = result[0]
const babelrcFileIsSame = result[1]
if (!babelrcFileIsSame || !isEqual(sourceHashes, expectedSourceHashes)) {
return { sourcesChanged: true }
}
return pendingDependencyHashes
.then(dependencyHashes => {
const dependenciesChanged = !isEqual(dependencyHashes, expectedDependencyHashes)
let verifier = this
if (dependenciesChanged) {
const dependencies = this.dependencies.map((item, index) => {
const hash = dependencyHashes[index]
return Object.assign({}, item, { hash })
})
verifier = new Verifier(this.babelrcDir, this.envNames, dependencies, this.sources)
}
return {
sourcesChanged: false,
dependenciesChanged,
cacheKeys: {
dependencies: md5Hex(dependencyHashes),
sources: md5Hex(sourceHashes)
},
verifier
}
})
})
.catch(err => {
if (err.name === 'NoSourceFileError') {
return {
missingSource: true
}
}
if (err.name === 'BadDependencyError') {
return {
badDependency: true
}
}
throw err
})
}
toBuffer () {
return SafeBuffer.from(JSON.stringify({
babelrcDir: this.babelrcDir,
envNames: this.envNames,
dependencies: this.dependencies,
sources: this.sources
}, (key, value) => {
return key === 'envNames' || key === 'envs'
? Array.from(value)
: value
}, 2))
}
static fromBuffer (buffer) {
const json = JSON.parse(buffer.toString('utf8'), (key, value) => {
return key === 'envNames' || key === 'envs'
? new Set(value)
: value
})
return new this(json.babelrcDir, json.envNames, json.dependencies, json.sources)
}
static hashAndCreate (babelrcDir, envNames, dependencies, sources, fixedSourceHashes, cache) {
return Promise.all([
hashDependencies(dependencies, cache),
hashSources(sources, fixedSourceHashes, cache)
])
.then(results => {
const dependencyHashes = results[0]
const sourceHashes = results[1]
dependencies.forEach((item, index) => {
item.hash = dependencyHashes[index]
})
sources.forEach((item, index) => {
item.hash = sourceHashes[index]
})
return new this(babelrcDir, envNames, dependencies, sources)
})
}
}
module.exports = Verifier