Skip to content

Commit

Permalink
Merge pull request #2087 from xodio/fix-one-settings-file-for-all-pro…
Browse files Browse the repository at this point in the history
…cesses

Fix: configure electron-settings for all kinds of processes
  • Loading branch information
brusherru authored Jan 20, 2021
2 parents b59e530 + b147b17 commit d2c5d15
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 17 deletions.
7 changes: 3 additions & 4 deletions packages/xod-client-electron/src/app/main.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ import {
IS_DEV,
getFilePathToOpen,
getPathToBundledWorkspace,
setUserDataArg,
getUserDataDir,
} from './utils';
import * as WA from './workspaceActions';
import {
Expand All @@ -61,12 +63,8 @@ app.setName('xod');

configureAutoUpdater(autoUpdater, log);

// to ensure compatibility with the old default
settings.rewriteElectronSettingsFileName('Settings');

if (process.env.USERDATA_DIR) {
app.setPath('userData', process.env.USERDATA_DIR);
settings.rewriteElectronSettingsFilePath(app.getPath('userData'));
}

if (IS_DEV) {
Expand Down Expand Up @@ -119,6 +117,7 @@ function createWindow() {
contextIsolation: false,
additionalArguments: [
IS_DEV ? 'ELECTRON_IS_DEV' : 'ELECTRON_IS_PACKAGED',
setUserDataArg(getUserDataDir()),
],
},
});
Expand Down
53 changes: 40 additions & 13 deletions packages/xod-client-electron/src/app/settings.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import * as R from 'ramda';
import electronSettings from 'electron-settings';

import { getUserDataDir } from './utils';

// =============================================================================
//
// Default settings object
Expand All @@ -15,22 +17,17 @@ export const DEFAULT_SETTINGS = {

// =============================================================================
//
// Unpure save / load / setDefaults settings
// Configure settings file
//
// The `electron-settings` pakage creates a `config` variable to store paths and
// file names in it. So separate processes, like main process and renderer
// will have the separate instances of this variable.
// To achieve the same data in all processes, we use utility `getUserDataDir`
// and will set the correct config for `electron-settings` every time we call to
// load or save the settings file.
//
// =============================================================================

// TODO: Add catching broken settings (if user opens settings file and break it)
// On catch — show error to user and fallback to default settings.
export const load = () => R.merge(DEFAULT_SETTINGS, electronSettings.getSync());

// TODO: Add schema and validating on save to prevent errors
export const save = settings => electronSettings.setSync(settings);

export const setDefaults = R.compose(
R.when(R.isEmpty, () => save(DEFAULT_SETTINGS)),
load
);

/**
* To make settings path changeble in dependency of env varialbe (E.G. for functional tests)
* we have to call this function before electron app onReady called.
Expand All @@ -48,6 +45,36 @@ export const rewriteElectronSettingsFileName = fileName => {
});
};

const ensureSettingsFileConfiguration = () => {
// to ensure compatibility with the old default
rewriteElectronSettingsFileName('Settings');
rewriteElectronSettingsFilePath(getUserDataDir());
};

// =============================================================================
//
// Unpure save / load / setDefaults settings
//
// =============================================================================

// TODO: Add catching broken settings (if user opens settings file and break it)
// On catch — show error to user and fallback to default settings.
export const load = () => {
ensureSettingsFileConfiguration();
return R.merge(DEFAULT_SETTINGS, electronSettings.getSync());
};

// TODO: Add schema and validating on save to prevent errors
export const save = settings => {
ensureSettingsFileConfiguration();
return electronSettings.setSync(settings);
};

export const setDefaults = R.compose(
R.when(R.isEmpty, () => save(DEFAULT_SETTINGS)),
load
);

// =============================================================================
//
// Workspace setters & getters
Expand Down
29 changes: 29 additions & 0 deletions packages/xod-client-electron/src/app/utils.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,40 @@ export const IS_DEV =
? process.argv.includes('ELECTRON_IS_DEV')
: !electron.app.isPackaged) || process.env.NODE_ENV === 'development';

const USERDATA_ARGNAME = '--userdata-dir=';

// Utility to set the user data directory arguments for the renerer processes
// from the main process on creating a renderer.
export const setUserDataArg = userDataDir =>
`${USERDATA_ARGNAME}${userDataDir}`;

export const getUserDataDir = () =>
process.type === 'renderer'
? R.compose(
R.slice(USERDATA_ARGNAME.length, Infinity),
R.find(arg => arg.startsWith(USERDATA_ARGNAME))
)(process.argv)
: process.env.USERDATA_DIR || electron.app.getPath('userData');

// =============================================================================
//
// IPC
//
// =============================================================================

// for IPC. see https://electron.atom.io/docs/api/remote/#remote-objects
// if we don't do this, we get empty objects on the other side instead of errors
export const errorToPlainObject = R.when(
R.is(Error),
R.converge(R.pick, [Object.getOwnPropertyNames, R.identity])
);

// =============================================================================
//
// Cross-platform
//
// =============================================================================

/**
* It provides one iterface for getting file path, that
* should be opened on start-up (if User opens associated file),
Expand Down Expand Up @@ -58,6 +85,8 @@ export const getFilePathToOpen = app => {
return () => pathToOpen;
};

// =============================================================================

/**
* Returns Path to the resources directory root.
*
Expand Down

0 comments on commit d2c5d15

Please sign in to comment.