all files / src/components/ initiator.js

100% Statements 76/76
100% Branches 26/26
100% Functions 0/0
100% Lines 72/72
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 12729×                     24× 12× 12× 12×   11× 11×                     32×   12×   11×                                                                
import _ from 'lodash'
import fs from 'fs-extra'
import createDebugger from 'debug'
import { isDirFilesInDir } from '../helpers/dir-analyzer.js'
import { ENV_PATH, UNI_ENV_PATH } from '../constants/paths.js'
import { ENV_PACKAGE_JSON_FILE } from '../constants/files.js'
import {
    INSTALLATION_DIRECTORY_NOT_EMPTY,
    UNKNOWN_ENV_DIRECTORY_ERROR,
    UNKNOWN_ENV_COPY_ERROR,
    UNKNOWN_ENV_PACKAGE_JSON_ERROR,
    LIKELY_NOT_UNI_ENV
} from '../constants/language/errors.js'
import { TOGGLE_ENV_INITIATED_FLAG } from '../constants/actionTypes.js'
import {
    handleError, setEnvFilesPresentFlag, setEnvPopulatedFlag
} from '../actions/creators.js'
 
const debug = createDebugger('unistack:initiator')
 
const Initiator = ({ dispatch, getState }) => {
    const state = getState()
    const envInitiated = getStateLeaf(state, 'ENV_INITIATED_FLAG')
    if (envInitiated) return
 
    const envFilesPresent = getStateLeaf(state, 'ENV_FILES_PRESENT_FLAG')
    if (envFilesPresent === null) return dispatch(isEnvFilesPresent())
 
    const envPopulated = getStateLeaf(state, 'ENV_POPULATED_FLAG')
    if (envFilesPresent === false) {
        switch(envPopulated) {
            case null:
                return dispatch(isEnvIsPopulated())
            case true:
                return dispatch(makeEnvPopulatedError())
            case false:
                return dispatch(setupNewEnv())
        }
    }
 
    const validPackageJSON = validatePackageJSON()
    if (validPackageJSON !== true) return dispatch(validPackageJSON)
 
    return dispatch({ type: TOGGLE_ENV_INITIATED_FLAG })
}
 
const getStateLeaf = (state, leaf) => {
    switch(leaf) {
        case 'ENV_INITIATED_FLAG':
            return state.env.initiated
        case 'ENV_FILES_PRESENT_FLAG':
            return state.env.filesPresent
        case 'ENV_POPULATED_FLAG':
            return state.env.populated
    }
}
 
const validatePackageJSON = () => {
    const packageJSON = getEnvPackageJSON()
    if (packageJSON instanceof Error || !_.isPlainObject(packageJSON)) {
        const message = UNKNOWN_ENV_PACKAGE_JSON_ERROR
        return handleError(packageJSON, { message, fatal: true })
    }
    if (!packageJSON.unistack) {
        return makeLikelyNotUniEnvError()
    }
    return true
}
 
const makeEnvPopulatedError = () => {
    const error = new Error(INSTALLATION_DIRECTORY_NOT_EMPTY)
    return handleError(error, { fatal: true })
}
 
const makeLikelyNotUniEnvError = () => {
    const error = new Error(LIKELY_NOT_UNI_ENV)
    return handleError(error)
}
 
const isEnvFilesPresent = () => {
    debug('Checking if environment file are present')
    const status = isDirFilesInDir(UNI_ENV_PATH, ENV_PATH)
    return setEnvFilesPresentFlag(status)
}
 
const isEnvIsPopulated = () => {
    debug('Checking if environment is populated')
    const status = isEnvPopulated()
    if (status instanceof Error) {
        const message = UNKNOWN_ENV_DIRECTORY_ERROR
        return handleError(status, { message, fatal: true })
    }
    return setEnvPopulatedFlag(status)
}
 
const setupNewEnv = () => {
    debug('Setting up new environment')
    const status = copyUniEnvToEnv()
    if (status instanceof Error) {
        const message = UNKNOWN_ENV_COPY_ERROR
        return handleError(status, { message, fatal: true })
    }
    return setEnvFilesPresentFlag(status)
}
 
const copyUniEnvToEnv = () => {
    try {
        fs.copySync(UNI_ENV_PATH, ENV_PATH)
        return true
    } catch (e) { return e }
}
 
const getEnvPackageJSON = () => {
    try {
        return require(ENV_PACKAGE_JSON_FILE)
    } catch (e) { return e }
}
 
const isEnvPopulated = () => {
    try {
        const files = fs.readdirSync(ENV_PATH)
        return (files.length === 0 ? false : true)
    } catch (e) { return e }
}
 
export default Initiator