Fixed flipper settings not being loaded / saved on fresh install
Summary: I was running flipper-server on a fresh machine without Flipper installed and discovered that reading / writing settings failed since `~/.flipper` wasn't existing, due to using `access` instead of `pathExists`. Added a warning about needing to restart the server after making changes, since that is tricky to do from the UI. Fixed an issue in the settings screen, which would fs.stat as part of rendering, causing the Settings UI not to load. Reviewed By: timur-valiev, aigoncharov Differential Revision: D32984538 fbshipit-source-id: 2b2011ad9d84c72ac824d92a8c96f636237b8771
This commit is contained in:
committed by
Facebook GitHub Bot
parent
4222acaf96
commit
bb23b36051
@@ -11,30 +11,39 @@ import os from 'os';
|
|||||||
import {resolve} from 'path';
|
import {resolve} from 'path';
|
||||||
import xdg from 'xdg-basedir';
|
import xdg from 'xdg-basedir';
|
||||||
import {Settings, Tristate} from 'flipper-common';
|
import {Settings, Tristate} from 'flipper-common';
|
||||||
import {readFile, writeFile, access} from 'fs-extra';
|
import {readFile, writeFile, pathExists, mkdirp} from 'fs-extra';
|
||||||
|
|
||||||
export async function loadSettings(): Promise<Settings> {
|
export async function loadSettings(): Promise<Settings> {
|
||||||
if (!access(getSettingsFile())) {
|
if (!pathExists(getSettingsFile())) {
|
||||||
return getDefaultSettings();
|
return getDefaultSettings();
|
||||||
}
|
}
|
||||||
|
try {
|
||||||
const json = await readFile(getSettingsFile(), {encoding: 'utf8'});
|
const json = await readFile(getSettingsFile(), {encoding: 'utf8'});
|
||||||
return JSON.parse(json);
|
return JSON.parse(json);
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Failed to load settings file', e);
|
||||||
|
return getDefaultSettings();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function saveSettings(settings: Settings): Promise<void> {
|
export async function saveSettings(settings: Settings): Promise<void> {
|
||||||
|
await mkdirp(getSettingsDir());
|
||||||
await writeFile(getSettingsFile(), JSON.stringify(settings, null, 2), {
|
await writeFile(getSettingsFile(), JSON.stringify(settings, null, 2), {
|
||||||
encoding: 'utf8',
|
encoding: 'utf8',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function getSettingsFile() {
|
function getSettingsDir() {
|
||||||
return resolve(
|
return resolve(
|
||||||
...(xdg.config ? [xdg.config] : [os.homedir(), '.config']),
|
...(xdg.config ? [xdg.config] : [os.homedir(), '.config']),
|
||||||
'flipper',
|
'flipper',
|
||||||
'settings.json',
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSettingsFile() {
|
||||||
|
return resolve(getSettingsDir(), 'settings.json');
|
||||||
|
}
|
||||||
|
|
||||||
export const DEFAULT_ANDROID_SDK_PATH = getDefaultAndroidSdkPath();
|
export const DEFAULT_ANDROID_SDK_PATH = getDefaultAndroidSdkPath();
|
||||||
|
|
||||||
function getDefaultSettings(): Settings {
|
function getDefaultSettings(): Settings {
|
||||||
|
|||||||
@@ -52,8 +52,9 @@ export function initializeRenderHost(
|
|||||||
);
|
);
|
||||||
},
|
},
|
||||||
restartFlipper() {
|
restartFlipper() {
|
||||||
// TODO: restart server as well
|
window.flipperShowError!(
|
||||||
window.location.reload();
|
'Flipper settings have changed, please restart flipper server for the changes to take effect',
|
||||||
|
);
|
||||||
},
|
},
|
||||||
loadDefaultPlugins: getDefaultPluginsIndex,
|
loadDefaultPlugins: getDefaultPluginsIndex,
|
||||||
serverConfig: flipperServerConfig,
|
serverConfig: flipperServerConfig,
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import React, {useState} from 'react';
|
|||||||
import {promises as fs} from 'fs';
|
import {promises as fs} from 'fs';
|
||||||
import {theme} from 'flipper-plugin';
|
import {theme} from 'flipper-plugin';
|
||||||
import {getRenderHostInstance} from '../../RenderHost';
|
import {getRenderHostInstance} from '../../RenderHost';
|
||||||
|
import {useEffect} from 'react';
|
||||||
|
|
||||||
export const ConfigFieldContainer = styled(FlexRow)({
|
export const ConfigFieldContainer = styled(FlexRow)({
|
||||||
paddingLeft: 10,
|
paddingLeft: 10,
|
||||||
@@ -70,14 +71,17 @@ export function FilePathConfigField(props: {
|
|||||||
const renderHost = getRenderHostInstance();
|
const renderHost = getRenderHostInstance();
|
||||||
const [value, setValue] = useState(props.defaultValue);
|
const [value, setValue] = useState(props.defaultValue);
|
||||||
const [isValid, setIsValid] = useState(true);
|
const [isValid, setIsValid] = useState(true);
|
||||||
fs.stat(value)
|
|
||||||
.then((stat) => props.isRegularFile !== stat.isDirectory())
|
useEffect(() => {
|
||||||
.then((valid) => {
|
(async function () {
|
||||||
if (valid !== isValid) {
|
try {
|
||||||
setIsValid(valid);
|
const stat = await fs.stat(value);
|
||||||
|
setIsValid(props.isRegularFile !== stat.isDirectory());
|
||||||
|
} catch (_) {
|
||||||
|
setIsValid(false);
|
||||||
}
|
}
|
||||||
})
|
})();
|
||||||
.catch((_) => setIsValid(false));
|
}, [props.isRegularFile, value]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ConfigFieldContainer>
|
<ConfigFieldContainer>
|
||||||
|
|||||||
Reference in New Issue
Block a user