diff --git a/app/config/import.js b/app/config/import.js index bfd2e81e..c779d72c 100644 --- a/app/config/import.js +++ b/app/config/import.js @@ -1,4 +1,4 @@ -const {moveSync, copySync, existsSync, writeFileSync, readFileSync} = require('fs-extra'); +const {moveSync, copySync, existsSync, writeFileSync, readFileSync, lstatSync} = require('fs-extra'); const {sync: mkdirpSync} = require('mkdirp'); const {defaultCfg, cfgPath, legacyCfgPath, plugs, defaultPlatformKeyPath} = require('./paths'); const {_init, _extractDefault} = require('./init'); @@ -37,41 +37,58 @@ const saveAsBackup = src => { throw new Error('Failed to create backup for config file. Too many backups'); }; -const migrate = (old, _new, oldBackupPath) => { - if (old === _new) { +// Migrate Hyper2 config to Hyper3 but only if the user hasn't manually +// touched the new config and if the old config is not a symlink +const migrateHyper2Config = () => { + if (cfgPath === legacyCfgPath) { + // No need to migrate 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; + if (!existsSync(legacyCfgPath)) { + // Already migrated or user never used Hyper 2 + return; } - return false; + const existsNew = existsSync(cfgPath); + if (lstatSync(legacyCfgPath).isSymbolicLink() || (existsNew && lstatSync(cfgPath).isSymbolicLink())) { + // One of the files is a symlink, there could be a number of complications + // in this case so let's avoid those and not do automatic migration + return; + } + + const hasNewConfigBeenTouched = existsNew && readFileSync(cfgPath, 'utf8') !== readFileSync(defaultCfg, 'utf8'); + if (hasNewConfigBeenTouched) { + // Assume the user has migrated manually but rename old config to .backup so + // we don't keep trying to migrate on every launch + const backupPath = saveAsBackup(legacyCfgPath); + notify( + 'Hyper 3', + `Settings location has changed to ${cfgPath}.\nWe've backed up your old Hyper config to ${backupPath}` + ); + return; + } + + // Migrate + copySync(legacyCfgPath, cfgPath); + saveAsBackup(legacyCfgPath); + + notify( + 'Hyper 3', + `Settings location has changed to ${cfgPath}.\nWe've automatically migrated your existing config!\nPlease restart Hyper now` + ); }; 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 { + migrateHyper2Config(); + } catch (err) { + //eslint-disable-next-line no-console + console.error(err); + } + try { const defaultCfgRaw = readFileSync(defaultCfg, 'utf8'); const _defaultCfg = _extractDefault(defaultCfgRaw);