Remove fs and os usage from Mobile Builds plugin

Summary: Changelog: Expose env info and FS rm command to flipper plugins.

Reviewed By: mweststrate

Differential Revision: D32988478

fbshipit-source-id: 3d0233f9eb34d3478b07e39b9401c0e30ca95135
This commit is contained in:
Andrey Goncharov
2021-12-10 06:34:37 -08:00
committed by Facebook GitHub Bot
parent adb2573a1f
commit c96558a524
15 changed files with 166 additions and 6 deletions

View File

@@ -21,6 +21,7 @@ export {sleep} from './utils/sleep';
export {timeout} from './utils/timeout';
export {isTest} from './utils/isTest';
export {assertNever} from './utils/assertNever';
export {fsConstants} from './utils/fsConstants';
export {
logPlatformSuccessRate,
reportPlatformFailures,

View File

@@ -140,6 +140,7 @@ export type FlipperServerCommands = {
path: string,
options?: {recursive?: boolean} & MkdirOptions,
) => Promise<string | void>;
'node-api-fs-rm': (path: string, options?: RmOptions) => Promise<void>;
'node-api-fs-copyFile': (
src: string,
dest: string,
@@ -332,6 +333,10 @@ export interface MkdirOptions {
mode?: string | number;
}
export interface RmOptions {
maxRetries?: number;
}
export interface DownloadFileStartOptions {
method?: 'GET' | 'POST';
timeout?: number;

View File

@@ -69,6 +69,19 @@ export type ProcessConfig = {
launcherEnabled: boolean;
};
export type Platform =
| 'aix'
| 'android'
| 'darwin'
| 'freebsd'
| 'haiku'
| 'linux'
| 'openbsd'
| 'sunos'
| 'win32'
| 'cygwin'
| 'netbsd';
export type EnvironmentInfo = {
processId: number;
isProduction: boolean;
@@ -77,7 +90,7 @@ export type EnvironmentInfo = {
appVersion: string;
os: {
arch: string;
platform: NodeJS.Platform;
platform: Platform;
unixname: string;
};
versions: {

View File

@@ -0,0 +1,67 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
// https://github.com/nodejs/node/blob/b66a75a3a4361614dde9bc1a52d7e9021b4efc26/typings/internalBinding/constants.d.ts
export const fsConstants = {
UV_FS_SYMLINK_DIR: 1,
UV_FS_SYMLINK_JUNCTION: 2,
O_RDONLY: 0,
O_WRONLY: 1,
O_RDWR: 2,
UV_DIRENT_UNKNOWN: 0,
UV_DIRENT_FILE: 1,
UV_DIRENT_DIR: 2,
UV_DIRENT_LINK: 3,
UV_DIRENT_FIFO: 4,
UV_DIRENT_SOCKET: 5,
UV_DIRENT_CHAR: 6,
UV_DIRENT_BLOCK: 7,
S_IFMT: 61440,
S_IFREG: 32768,
S_IFDIR: 16384,
S_IFCHR: 8192,
S_IFBLK: 24576,
S_IFIFO: 4096,
S_IFLNK: 40960,
S_IFSOCK: 49152,
O_CREAT: 512,
O_EXCL: 2048,
UV_FS_O_FILEMAP: 0,
O_NOCTTY: 131072,
O_TRUNC: 1024,
O_APPEND: 8,
O_DIRECTORY: 1048576,
O_NOFOLLOW: 256,
O_SYNC: 128,
O_DSYNC: 4194304,
O_SYMLINK: 2097152,
O_NONBLOCK: 4,
S_IRWXU: 448,
S_IRUSR: 256,
S_IWUSR: 128,
S_IXUSR: 64,
S_IRWXG: 56,
S_IRGRP: 32,
S_IWGRP: 16,
S_IXGRP: 8,
S_IRWXO: 7,
S_IROTH: 4,
S_IWOTH: 2,
S_IXOTH: 1,
F_OK: 0,
R_OK: 4,
W_OK: 2,
X_OK: 1,
UV_FS_COPYFILE_EXCL: 1,
COPYFILE_EXCL: 1,
UV_FS_COPYFILE_FICLONE: 2,
COPYFILE_FICLONE: 2,
UV_FS_COPYFILE_FICLONE_FORCE: 4,
COPYFILE_FICLONE_FORCE: 4,
};

View File

@@ -13,7 +13,6 @@
"@emotion/css": "^11.5.0",
"@emotion/react": "^11.6.0",
"@reach/observe-rect": "^1.2.0",
"@types/uuid": "^8.3.1",
"eventemitter3": "^4.0.7",
"flipper-common": "0.0.0",
"immer": "^9.0.6",
@@ -27,6 +26,7 @@
},
"devDependencies": {
"@types/string-natural-compare": "^3.0.2",
"@types/uuid": "^8.3.3",
"jest-mock-console": "^1.2.3",
"typescript": "^4.4.4"
},

View File

@@ -70,6 +70,7 @@ test('Correct top level API exposed', () => {
"usePlugin",
"useTrackedCallback",
"useValue",
"uuid",
"withTrackingScope",
]
`);

View File

@@ -133,6 +133,7 @@ export {createTablePlugin} from './utils/createTablePlugin';
export {textContent} from './utils/textContent';
import * as path from './utils/path';
export {path};
export * from './utils/uuid';
// It's not ideal that this exists in flipper-plugin sources directly,
// but is the least pain for plugin authors.

View File

@@ -21,6 +21,9 @@ import {
DownloadFileStartOptions,
DownloadFileStartResponse,
DownloadFileUpdate,
RmOptions,
fsConstants,
EnvironmentInfo,
} from 'flipper-common';
export type FileEncoding = 'utf-8' | 'base64';
@@ -57,7 +60,9 @@ export type RemoteServerContext = {
path: string,
options?: {recursive?: false} & MkdirOptions,
): Promise<void>;
rm(path: string, options?: RmOptions): Promise<void>;
copyFile(src: string, dest: string, flags?: number): Promise<void>;
constants: typeof fsConstants;
};
downloadFile(
url: string,
@@ -150,6 +155,10 @@ export interface FlipperLib {
paths: {
homePath: string;
appPath: string;
tempPath: string;
};
environmentInfo: {
os: EnvironmentInfo['os'];
};
remoteServerContext: RemoteServerContext;
}

View File

@@ -14,7 +14,11 @@ import {
act as testingLibAct,
} from '@testing-library/react';
import {queries} from '@testing-library/dom';
import {BundledPluginDetails, InstalledPluginDetails} from 'flipper-common';
import {
BundledPluginDetails,
fsConstants,
InstalledPluginDetails,
} from 'flipper-common';
import {
RealFlipperClient,
@@ -388,6 +392,14 @@ export function createMockFlipperLib(options?: StartPluginOptions): FlipperLib {
paths: {
appPath: process.cwd(),
homePath: `/dev/null`,
tempPath: `/dev/null`,
},
environmentInfo: {
os: {
arch: 'Test',
unixname: 'test',
platform: 'linux',
},
},
remoteServerContext: {
childProcess: {
@@ -398,7 +410,9 @@ export function createMockFlipperLib(options?: StartPluginOptions): FlipperLib {
pathExists: jest.fn(),
unlink: jest.fn(),
mkdir: jest.fn(),
rm: jest.fn(),
copyFile: jest.fn(),
constants: fsConstants,
},
downloadFile: jest.fn(),
},

View File

@@ -0,0 +1,11 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @format
*/
import {v4 as uuid} from 'uuid';
export {uuid};

View File

@@ -28,6 +28,7 @@
"open": "^8.3.0",
"openssl-wrapper": "^0.3.4",
"promisify-child-process": "^4.1.1",
"rimraf": "^3.0.2",
"rsocket-core": "^0.0.27",
"rsocket-flowable": "^0.0.27",
"rsocket-tcp-server": "^0.0.25",
@@ -43,6 +44,7 @@
"devDependencies": {
"@types/memorystream": "^0.3.0",
"@types/node": "^15.12.5",
"@types/rimraf": "^3.0.2",
"@types/tmp": "^0.2.2",
"memorystream": "^0.3.1",
"tmp": "^0.2.1"

View File

@@ -46,6 +46,8 @@ import {
import {commandNodeApiExec} from './commands/NodeApiExec';
import {commandDownloadFileStartFactory} from './commands/DownloadFile';
import {promises} from 'fs';
// Electron 11 runs on Node 12 which does not support fs.promises.rm
import rm from 'rimraf';
const {access, copyFile, mkdir, unlink} = promises;
@@ -230,6 +232,12 @@ export class FlipperServerImpl implements FlipperServer {
},
'node-api-fs-unlink': unlink,
'node-api-fs-mkdir': mkdir,
'node-api-fs-rm': async (path, {maxRetries} = {}) =>
new Promise<void>((resolve, reject) =>
rm(path, {disableGlob: true, maxBusyTries: maxRetries}, (err) =>
err ? reject(err) : resolve(),
),
),
'node-api-fs-copyFile': copyFile,
// TODO: Do we need API to cancel an active download?
'download-file-start': commandDownloadFileStartFactory(

View File

@@ -14,8 +14,10 @@ import {
import {
BufferEncoding,
ExecOptions,
fsConstants,
Logger,
MkdirOptions,
RmOptions,
} from 'flipper-common';
import type {Store} from '../../reducers';
import createPaste from '../../fb-stubs/createPaste';
@@ -71,6 +73,10 @@ export function initializeFlipperLibImplementation(
paths: {
appPath: renderHost.serverConfig.paths.appPath,
homePath: renderHost.serverConfig.paths.homePath,
tempPath: renderHost.serverConfig.paths.tempPath,
},
environmentInfo: {
os: renderHost.serverConfig.environmentInfo.os,
},
remoteServerContext: {
childProcess: {
@@ -95,6 +101,8 @@ export function initializeFlipperLibImplementation(
path,
options,
)) as RemoteServerContext['fs']['mkdir'],
rm: async (path: string, options?: RmOptions) =>
renderHost.flipperServer.exec('node-api-fs-rm', path, options),
copyFile: async (src: string, dest: string, flags?: number) =>
renderHost.flipperServer.exec(
'node-api-fs-copyFile',
@@ -102,6 +110,7 @@ export function initializeFlipperLibImplementation(
dest,
flags,
),
constants: fsConstants,
},
downloadFile: downloadFileFactory(renderHost),
},

View File

@@ -3046,6 +3046,14 @@
resolved "https://registry.yarnpkg.com/@types/retry/-/retry-0.12.0.tgz#2b35eccfcee7d38cd72ad99232fbd58bffb3c84d"
integrity sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==
"@types/rimraf@^3.0.2":
version "3.0.2"
resolved "https://registry.yarnpkg.com/@types/rimraf/-/rimraf-3.0.2.tgz#a63d175b331748e5220ad48c901d7bbf1f44eef8"
integrity sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==
dependencies:
"@types/glob" "*"
"@types/node" "*"
"@types/rsocket-core@*", "@types/rsocket-core@^0.0.7":
version "0.0.7"
resolved "https://registry.yarnpkg.com/@types/rsocket-core/-/rsocket-core-0.0.7.tgz#e9ed6d9ec918ec7a9aab0c48fefbb74b33712235"
@@ -3174,6 +3182,11 @@
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.1.tgz#1a32969cf8f0364b3d8c8af9cc3555b7805df14f"
integrity sha512-Y2mHTRAbqfFkpjldbkHGY8JIzRN6XqYRliG8/24FcHm2D2PwW24fl5xMRTVGdrb7iMrwCaIEbLWerGIkXuFWVg==
"@types/uuid@^8.3.3":
version "8.3.3"
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.3.tgz#c6a60686d953dbd1b1d45e66f4ecdbd5d471b4d0"
integrity sha512-0LbEEx1zxrYB3pgpd1M5lEhLcXjKJnYghvhTRgaBeUivLHMDM1TzF3IJ6hXU2+8uA4Xz+5BA63mtZo5DjVT8iA==
"@types/verror@^1.10.3":
version "1.10.4"
resolved "https://registry.yarnpkg.com/@types/verror/-/verror-1.10.4.tgz#805c0612b3a0c124cf99f517364142946b74ba3b"
@@ -6795,9 +6808,9 @@ flow-parser@0.*:
integrity sha512-IVHejqogTgZL2e206twVsdfX5he6mXS5F0AY315ao+6rEifbElEoVWKLYdEBsVl7QMp4buPbMe5FqXSdYQMUSQ==
follow-redirects@^1.14.0:
version "1.14.5"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.5.tgz#f09a5848981d3c772b5392309778523f8d85c381"
integrity sha512-wtphSXy7d4/OR+MvIFbCVBDzZ5520qV8XfPklSN5QtxuMUJZ+b0Wnst1e1lCDocfzuCkHqj8k0FpZqO+UIaKNA==
version "1.14.6"
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.6.tgz#8cfb281bbc035b3c067d6cd975b0f6ade6e855cd"
integrity sha512-fhUl5EwSJbbl8AR+uYL2KQDxLkdSjZGR36xy46AO7cOMTrCMON6Sa28FmAnC2tRTDbd/Uuzz3aJBv7EBN7JH8A==
for-in@^1.0.2:
version "1.0.2"

View File

@@ -1160,6 +1160,12 @@ path.normalize('/foo/bar//baz/asdf/quux/..');
// Returns: '/foo/bar/baz/asdf'
```
### uuid
Usage: `uuid()`
Returns UUID V4.
## TestUtils
The object `TestUtils` as exposed from `flipper-plugin` exposes utilities to write unit tests for Sandy plugins.