All files / skeleton desktopPathResolver.js

97.44% Statements 38/39
100% Branches 20/20
100% Functions 4/4
97.44% Lines 38/39
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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153                    39x 39x                       11x   11x                       6x                             11x     11x   11x     11x   11x   11x   11x 1x   1x     10x   9x       5x   4x       3x           3x 2x 1x         1x     1x         1x         1x       1x     4x       3x       3x 2x 1x     1x     1x       1x         1x       1x   10x        
import path, { join } from 'path';
import fs from 'fs';
 
export default class DesktopPathResolver {
 
    /**
     * Reads a json file.
     * @returns {Object}
     */
    static readJsonFile(jsonFilePath) {
        try {
            return JSON.parse(fs.readFileSync(jsonFilePath, 'UTF-8'));
        } catch (e) {
            return {};
        }
    }
 
    /**
     * Reads meteor app version from the initial asset bundle.
     * @returns {string}
     */
    static readInitialAssetBundleVersion() {
        const initialAssetBundleManifestPath =
            path.resolve(join(__dirname, '..', 'meteor.asar', 'program.json'));
 
        return DesktopPathResolver.readJsonFile(initialAssetBundleManifestPath).version;
    }
 
 
    /**
     * Tries to read information about bundled desktop version.
     *
     * @param {string} userDataDir - user data path
     * @param {string} version     - meteor app version
     * @returns {Object}
     */
    static readDesktopVersionInfoFromBundle(userDataDir, version) {
        return DesktopPathResolver
            .readJsonFile(join(userDataDir, 'versions', version, '_desktop.json'));
    }
 
 
    /**
     * Decides where the current desktop.asar lies. Takes into account desktopHCP.
     * Also supports falling back to last known good version Meteor mechanism.
     *
     * @param {string} userDataDir - user data path
     * @param {Log}    log         - App's logger instance
     */
    static resolveDesktopPath(userDataDir, log) {
        // TODO: kinda the same logic is in the autoupdate module - extract it to common place.
 
        let desktopPath = path.resolve(join(__dirname, '..', 'desktop.asar'));
 
        const initialDesktopVersion =
            DesktopPathResolver.readJsonFile(join(desktopPath, 'settings.json')).desktopVersion;
 
        log.info('initial desktop version is ', initialDesktopVersion);
 
        // Read meteor's initial asset bundle version.
        const initialVersion = DesktopPathResolver.readInitialAssetBundleVersion();
 
        this.autoupdate = null;
        const autoupdateConfig =
            DesktopPathResolver.readJsonFile(join(userDataDir, 'autoupdate.json'));
 
        if (autoupdateConfig.lastSeenInitialVersion !== initialVersion) {
            log.warn('will use desktop.asar from initial version because the initial version ' +
            `of meteor app has changed: ${desktopPath}`);
            return desktopPath;
        }
 
        if (autoupdateConfig.lastDownloadedVersion) {
            // We have a last downloaded version.
            if (~autoupdateConfig.blacklistedVersions.indexOf(
                autoupdateConfig.lastDownloadedVersion)
            ) {
                // If it is blacklisted lets check if we have last known good version.
                if (autoupdateConfig.lastKnownGoodVersion) {
                    // But is the last know good version is different from the initial version?
                    if (autoupdateConfig.lastKnownGoodVersion !==
                        autoupdateConfig.lastSeenInitialVersion
                    ) {
                        const desktopVersion =
                            DesktopPathResolver.readDesktopVersionInfoFromBundle(
                                userDataDir,
                                autoupdateConfig.lastKnownGoodVersion
                            );
 
                        // TODO: can we assume that desktopHCP is on?
                        if (desktopVersion.version) {
                            if (desktopVersion.version !== initialDesktopVersion) {
                                desktopPath =
                                    join(
                                        __dirname,
                                        `${desktopVersion.version}_desktop.asar`
                                    );
                                log.warn('will use desktop.asar from last known good version ' +
                                    `at: ${desktopPath}`);
                            } else {
                                log.warn('will use desktop.asar from initial version because ' +
                                    'last known good version of meteor app is using it: ' +
                                    `${desktopPath}`);
                            }
                        } else {
                            log.warn('will use desktop.asar from initial version because last ' +
                                'known good version of meteor app does not contain new desktop ' +
                                `version : ${desktopPath}`);
                        }
                    } else {
                        log.info('will use desktop.asar from last known good version which is ' +
                            `apparently the initial bundle: ${desktopPath}`);
                    }
                } else {
                    log.warn('will use desktop.asar from initial version as a fallback: ' +
                        `${desktopPath}`);
                }
            } else if (autoupdateConfig.lastDownloadedVersion !==
                    autoupdateConfig.lastSeenInitialVersion
            ) {
                const desktopVersion =
                    this.readDesktopVersionInfoFromBundle(
                        userDataDir,
                        autoupdateConfig.lastDownloadedVersion
                    );
                if (desktopVersion.version) {
                    if (desktopVersion.version !== initialDesktopVersion) {
                        desktopPath = join(
                            __dirname,
                            `${desktopVersion.version}_desktop.asar`);
                        log.info('will use desktop.asar from last downloaded version ' +
                            `at: ${desktopPath}`);
                    } else {
                        log.warn('will use desktop.asar from initial version because last ' +
                            `downloaded version is using it: ${desktopPath}`);
                    }
                } else {
                    log.warn('will use desktop.asar from initial version because last ' +
                        'downloaded version does not contain new desktop version: ' +
                        `${desktopPath}`);
                }
            } else {
                log.info('will use desktop.asar from last downloaded version which is ' +
                    `apparently the initial bundle: ${desktopPath}`);
            }
        } else {
            log.info(`using desktop.asar from initial bundle: ${desktopPath}`);
        }
        return desktopPath;
    }
 
}