🏡 index : quine-global/hyper.git

const {moveSync, copySync, existsSync, writeFileSync, readFileSync} = require('fs-extra');
const {sync: mkdirpSync} = require('mkdirp');
const {defaultCfg, cfgPath, legacyCfgPath, plugs, defaultPlatformKeyPath} = require('./paths');
const {_init, _extractDefault} = require('./init');
const notify = require('../notify');

let defaultConfig;

const _write = function(path, data) {
  // This method will take text formatted as Unix line endings and transform it
  // to text formatted with DOS line endings. We do this because the default
  // text editor on Windows (notepad) doesn't Deal with LF files. Still. In 2017.
  const crlfify = function(str) {
    return str.replace(/\r?\n/g, '\r\n');
  };
  const format = process.platform === 'win32' ? crlfify(data.toString()) : data;
  writeFileSync(path, format, 'utf8');
};

// Saves a file as backup by appending '.backup' or '.backup2', '.backup3', etc.
// so as to not override any existing files
const saveAsBackup = src => {
  let attempt = 1;
  while (attempt < 100) {
    try {
      const backupPath = src + '.backup' + (attempt === 1 ? '' : attempt);
      moveSync(src, backupPath);
      return backupPath;
    } catch (e) {
      if (e.code === 'EEXIST') {
        attempt++;
      } else {
        throw e;
      }
    }
  }
  throw new Error('Failed to create backup for config file. Too many backups');
};

const migrate = (old, _new, oldBackupPath) => {
  if (old === _new) {
    return;
  }
  if (existsSync(old)) {
    //eslint-disable-next-line no-console
    console.log('Found legacy config. Migrating ', old, '->', _new);
    if (existsSync(_new)) {
      saveAsBackup(_new);
    }
    copySync(old, _new);
    saveAsBackup(oldBackupPath || old);
    return true;
  }
  return false;
};

const _importConf = function() {
  // init plugin directories if not present
  mkdirpSync(plugs.base);

  // Migrate Hyper2 config to Hyper3
  const migratedConfig = migrate(legacyCfgPath, cfgPath);
  const migratedPlugins = migrate(plugs.legacyLocal, plugs.local, plugs.legacyBase);
  if (migratedConfig || migratedPlugins) {
    notify(
      'Hyper 3',
      `Settings location has changed to ${cfgPath}.\nWe've automatically migrated your existing config!\nPlease restart hyper`
    );
  }

  // Run this after the migration so that we don't generate a ".backup" file for
  // an empty local/ directory
  mkdirpSync(plugs.local);

  try {
    const defaultCfgRaw = readFileSync(defaultCfg, 'utf8');
    const _defaultCfg = _extractDefault(defaultCfgRaw);
    // Importing platform specific keymap
    try {
      const content = readFileSync(defaultPlatformKeyPath(), 'utf8');
      const mapping = JSON.parse(content);
      _defaultCfg.keymaps = mapping;
    } catch (err) {
      //eslint-disable-next-line no-console
      console.error(err);
    }

    // Import user config
    try {
      const userCfg = readFileSync(cfgPath, 'utf8');
      return {userCfg, defaultCfg: _defaultCfg};
    } catch (err) {
      _write(cfgPath, defaultCfgRaw);
      return {userCfg: defaultCfgRaw, defaultCfg: _defaultCfg};
    }
  } catch (err) {
    //eslint-disable-next-line no-console
    console.log(err);
  }
};

exports._import = () => {
  const imported = _importConf();
  defaultConfig = imported.defaultCfg;
  const result = _init(imported);
  return result;
};

exports.getDefaultConfig = () => {
  if (!defaultConfig) {
    defaultConfig = _extractDefault(_importConf().defaultCfg);
  }
  return defaultConfig;
};