All files / skeleton desktopPathResolver.js

61.54% Statements 24/39
40% Branches 8/20
100% Functions 4/4
61.54% Lines 24/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                    10x 10x                       3x   3x                       1x                             3x     3x   3x     3x   3x   3x   3x 1x   1x     2x   1x                                                                                     1x       1x       1x 1x 1x     1x                               1x   2x        
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.
            Iif (~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 Eif (autoupdateConfig.lastDownloadedVersion !==
                    autoupdateConfig.lastSeenInitialVersion
            ) {
                const desktopVersion =
                    this.readDesktopVersionInfoFromBundle(
                        userDataDir,
                        autoupdateConfig.lastDownloadedVersion
                    );
                Eif (desktopVersion.version) {
                    Eif (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;
    }
 
}