Use native fs promises rather than promisify or mz

Change-type: patch
This commit is contained in:
Pagan Gazzard 2020-06-23 11:57:57 +01:00
parent 14ce4d73b6
commit b114697cab
22 changed files with 67 additions and 61 deletions

View File

@ -17,7 +17,7 @@
const { stripIndent } = require('common-tags');
const _ = require('lodash');
const { fs } = require('mz');
const { promises: fs } = require('fs');
const path = require('path');
const simplegit = require('simple-git/promise');

View File

@ -73,9 +73,8 @@ export default class KeyAddCmd extends Command {
let key: string;
if (params.path != null) {
const { promisify } = await import('util');
const readFileAsync = promisify((await import('fs')).readFile);
key = await readFileAsync(params.path, 'utf8');
const { readFile } = (await import('fs')).promises;
key = await readFile(params.path, 'utf8');
} else if (this.stdin.length > 0) {
key = this.stdin;
} else {

View File

@ -184,7 +184,7 @@ export default class OsConfigureCmd extends Command {
await validateOptions(options);
const devInit = await import('balena-device-init');
const fs = await import('mz/fs');
const { promises: fs } = await import('fs');
const { generateDeviceConfig, generateApplicationConfig } = await import(
'../../utils/config'
);

View File

@ -154,17 +154,16 @@ Examples:
root: true,
action(params, options) {
const Bluebird = require('bluebird');
const util = require('util');
const config = require('balena-config-json');
const umountAsync = Bluebird.promisify(require('umount').umount);
const readFileAsync = util.promisify(require('fs').readFile);
return Bluebird.try(
() => options.drive || getVisuals().drive('Select the device drive'),
)
.tap(umountAsync)
.then((drive) =>
readFileAsync(params.file, 'utf8')
require('fs')
.promises.readFile(params.file, 'utf8')
.then(JSON.parse)
.then((configJSON) => config.write(drive, options.type, configJSON)),
)
@ -312,7 +311,6 @@ Examples:
action(_params, options) {
normalizeUuidProp(options, 'device');
const Bluebird = require('bluebird');
const writeFileAsync = Bluebird.promisify(require('fs').writeFile);
const balena = getBalenaSdk();
const form = require('resin-cli-form');
const prettyjson = require('prettyjson');
@ -408,7 +406,10 @@ See the help page for examples:
})
.then(function (config) {
if (options.output != null) {
return writeFileAsync(options.output, JSON.stringify(config));
return require('fs').promises.writeFile(
options.output,
JSON.stringify(config),
);
}
console.log(prettyjson.render(config));

View File

@ -238,16 +238,15 @@ Example:
},
],
action(params, options) {
const fs = require('fs');
const Bluebird = require('bluebird');
const writeFileAsync = Bluebird.promisify(fs.writeFile);
return $buildConfig(
params.image,
params['device-type'],
options.advanced,
).then((answers) =>
writeFileAsync(options.output, JSON.stringify(answers, null, 4)),
require('fs').promises.writeFile(
options.output,
JSON.stringify(answers, null, 4),
),
);
},
};

View File

@ -77,7 +77,7 @@ async function getContainerId(
// We need to execute a balena ps command on the device,
// and parse the output, looking for a specific
// container
const { child_process } = await import('mz');
const childProcess = await import('child_process');
const escapeRegex = await import('lodash/escapeRegExp');
const { which } = await import('../utils/helpers');
const { deviceContainerEngineBinary } = await import('../utils/device/ssh');
@ -96,7 +96,7 @@ async function getContainerId(
if (process.env.DEBUG) {
console.error(`[debug] [${sshBinary}, ${sshArgs.join(', ')}]`);
}
const subprocess = child_process.spawn(sshBinary, sshArgs, {
const subprocess = childProcess.spawn(sshBinary, sshArgs, {
stdio: [null, 'pipe', null],
});
const containers = await new Promise<string>((resolve, reject) => {

View File

@ -119,7 +119,7 @@ Source files are not modified.`,
* @returns Promise<{import('./compose-types').ComposeOpts}>
*/
export function generateOpts(options) {
const fs = require('mz/fs');
const { promises: fs } = require('fs');
const { isV12 } = require('./version');
return fs.realpath(options.source || '.').then((projectPath) => ({
projectName: options.projectName,
@ -213,7 +213,7 @@ function originalTarDirectory(dir, param) {
const tar = require('tar-stream');
const klaw = require('klaw');
const fs = require('mz/fs');
const { promises: fs } = require('fs');
const streamToPromise = require('stream-to-promise');
const { printGitignoreWarn } = require('./compose_ts');
const { FileIgnorer, IgnoreFileType } = require('./ignore');

View File

@ -19,7 +19,7 @@ import * as Bluebird from 'bluebird';
import { stripIndent } from 'common-tags';
import type * as Dockerode from 'dockerode';
import * as _ from 'lodash';
import { fs } from 'mz';
import { promises as fs } from 'fs';
import * as path from 'path';
import { Composition } from 'resin-compose-parse';
import * as MultiBuild from 'resin-multibuild';
@ -46,6 +46,15 @@ export interface RegistrySecrets {
};
}
const exists = async (filename: string) => {
try {
await fs.access(filename);
return true;
} catch {
return false;
}
};
const compositionFileNames = ['docker-compose.yml', 'docker-compose.yaml'];
/**
@ -101,11 +110,11 @@ async function resolveProject(
let composeFileContents = '';
for (const fname of compositionFileNames) {
const fpath = path.join(projectRoot, fname);
if (await fs.exists(fpath)) {
if (await exists(fpath)) {
logger.logDebug(`${fname} file found at "${projectRoot}"`);
composeFileName = fname;
try {
composeFileContents = await fs.readFile(fpath, 'utf-8');
composeFileContents = await fs.readFile(fpath, 'utf8');
} catch (err) {
logger.logError(`Error reading composition file "${fpath}":\n${err}`);
throw err;
@ -330,7 +339,7 @@ export async function getRegistrySecrets(
];
for (const potentialPath of potentialPaths) {
if (await fs.exists(potentialPath)) {
if (await exists(potentialPath)) {
return await parseRegistrySecrets(potentialPath);
}
}
@ -506,7 +515,7 @@ async function validateSpecifiedDockerfile(
const fullDockerfilePath = path.join(nativeProjectPath, nativeDockerfilePath);
if (!(await fs.exists(fullDockerfilePath))) {
if (!(await exists(fullDockerfilePath))) {
throw new ExpectedError(stripIndent`
Error: specified Dockerfile not found:
Specified dockerfile: "${fullDockerfilePath}"
@ -550,7 +559,7 @@ export async function validateProjectDirectory(
},
): Promise<ProjectValidationResult> {
if (
!(await fs.exists(opts.projectPath)) ||
!(await exists(opts.projectPath)) ||
!(await fs.stat(opts.projectPath)).isDirectory()
) {
throw new ExpectedError(
@ -585,7 +594,7 @@ export async function validateProjectDirectory(
return _.some(
await Promise.all(
compositionFileNames.map((filename) =>
fs.exists(path.join(folder, filename)),
exists(path.join(folder, filename)),
),
),
);

View File

@ -187,9 +187,9 @@ export const deployLegacy = function (
// If the file was never written to (for instance because an error
// has occured before any data was written) this call will throw an
// ugly error, just suppress it
Bluebird.try(() => require('mz/fs').unlink(bufferFile)).catchReturn(
undefined,
),
Bluebird.try(() =>
require('fs').promises.unlink(bufferFile),
).catchReturn(undefined),
);
})
.tap(function ({ buildId }) {

View File

@ -107,7 +107,7 @@ Implements the same feature as the "docker build --cache-from" option.`,
}
const generateConnectOpts = function (opts) {
const fs = require('mz/fs');
const { promises: fs } = require('fs');
return Bluebird.try(function () {
const connectOpts = {};

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
import { fs } from 'mz';
import { promises as fs } from 'fs';
import Logger = require('./logger');
import { isV12 } from './version';

View File

@ -15,7 +15,7 @@
* limitations under the License.
*/
import * as _ from 'lodash';
import { fs } from 'mz';
import { promises as fs, Stats } from 'fs';
import * as path from 'path';
import * as MultiBuild from 'resin-multibuild';
@ -193,7 +193,7 @@ export class FileIgnorer {
export interface FileStats {
filePath: string;
relPath: string;
stats: fs.Stats;
stats: Stats;
}
/**

View File

@ -33,12 +33,12 @@ export function qemuPathInContext(context: string) {
export function copyQemu(context: string, arch: string) {
const path = require('path') as typeof import('path');
const fs = require('mz/fs') as typeof import('mz/fs');
const fs = require('fs') as typeof import('fs');
// Create a hidden directory in the build context, containing qemu
const binDir = path.join(context, '.balena');
const binPath = path.join(binDir, QEMU_BIN_NAME);
return Bluebird.resolve(fs.mkdir(binDir))
return Bluebird.resolve(fs.promises.mkdir(binDir))
.catch({ code: 'EEXIST' }, function () {
// noop
})
@ -56,14 +56,14 @@ export function copyQemu(context: string, arch: string) {
.on('finish', resolve);
}),
)
.then(() => fs.chmod(binPath, '755'))
.then(() => fs.promises.chmod(binPath, '755'))
.then(() => path.relative(context, binPath));
}
export const getQemuPath = function (arch: string) {
const balena = getBalenaSdk();
const path = require('path') as typeof import('path');
const fs = require('mz/fs') as typeof import('mz/fs');
const { promises: fs } = require('fs') as typeof import('fs');
return balena.settings.get('binDirectory').then((binDir) =>
Bluebird.resolve(fs.mkdir(binDir))
@ -144,8 +144,12 @@ export async function installQemuIfNeeded(
if (!emulated || !needsQemu) {
return false;
}
const fs = await import('mz/fs');
if (!(await fs.exists(await getQemuPath(arch)))) {
const { promises: fs } = await import('fs');
const qemuPath = await getQemuPath(arch);
try {
await fs.access(qemuPath);
} catch {
// Qemu doesn't exist so install it
logger.logInfo(`Installing qemu for ${arch} emulation...`);
await installQemu(arch);
}

9
npm-shrinkwrap.json generated
View File

@ -1340,15 +1340,6 @@
"moment": ">=2.14.0"
}
},
"@types/mz": {
"version": "2.7.0",
"resolved": "https://registry.npmjs.org/@types/mz/-/mz-2.7.0.tgz",
"integrity": "sha512-Q5TZYMKnH0hdV5fNstmMWL2LLw5eRRtTd73KNtsZxoQ2gtCQyET5X79uERUEwGneuxPglg441I7OSY00+9CkSw==",
"dev": true,
"requires": {
"@types/node": "*"
}
},
"@types/net-keepalive": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@types/net-keepalive/-/net-keepalive-0.4.0.tgz",

View File

@ -131,7 +131,6 @@
"@types/mocha": "^5.2.7",
"@types/mock-require": "^2.0.0",
"@types/moment-duration-format": "^2.2.2",
"@types/mz": "^2.7.0",
"@types/net-keepalive": "^0.4.0",
"@types/nock": "^11.0.7",
"@types/node": "^10.17.20",
@ -232,7 +231,6 @@
"mkdirp": "^0.5.1",
"moment": "^2.24.0",
"moment-duration-format": "^2.3.2",
"mz": "^2.7.0",
"node-cleanup": "^2.1.2",
"node-unzip-2": "^0.2.8",
"oclif": "^1.15.2",

View File

@ -21,7 +21,7 @@ require('../config-tests'); // required for side effects
import { expect } from 'chai';
import { stripIndent } from 'common-tags';
import mock = require('mock-require');
import { fs } from 'mz';
import { promises as fs } from 'fs';
import * as path from 'path';
import { BalenaAPIMock } from '../balena-api-mock';
@ -193,7 +193,7 @@ describe('balena build', function () {
}
const arch = 'rpi';
const deviceType = 'raspberry-pi';
const fsModPath = 'mz/fs';
const fsModPath = 'fs';
const fsMod = await import(fsModPath);
const qemuModPath = '../../build/utils/qemu';
const qemuMod = require(qemuModPath);
@ -201,8 +201,11 @@ describe('balena build', function () {
try {
mock(fsModPath, {
...fsMod,
exists: async (p: string) =>
p === qemuBinPath ? true : fsMod.exists(p),
promises: {
...fsMod.promises,
access: async (p: string) =>
p === qemuBinPath ? undefined : fsMod.promises.access(p),
},
});
mock(qemuModPath, {
...qemuMod,

View File

@ -19,7 +19,7 @@
require('../config-tests'); // required for side effects
import { expect } from 'chai';
import { fs } from 'mz';
import { promises as fs } from 'fs';
import * as path from 'path';
import * as sinon from 'sinon';

View File

@ -1,5 +1,5 @@
import { expect } from 'chai';
import * as fs from 'mz/fs';
import { promises as fs } from 'fs';
import * as process from 'process';
import { runCommand } from '../../helpers';

View File

@ -19,7 +19,7 @@
require('../config-tests'); // required for side effects
import { expect } from 'chai';
import { fs } from 'mz';
import { promises as fs } from 'fs';
import * as path from 'path';
import { BalenaAPIMock } from '../balena-api-mock';

View File

@ -18,7 +18,7 @@
import { expect } from 'chai';
import { stripIndent } from 'common-tags';
import * as _ from 'lodash';
import { fs } from 'mz';
import { promises as fs } from 'fs';
import * as path from 'path';
import { PathUtils } from 'resin-multibuild';
import * as sinon from 'sinon';

View File

@ -21,7 +21,7 @@ require('./config-tests'); // required for side effects
import { execFile } from 'child_process';
import intercept = require('intercept-stdout');
import * as _ from 'lodash';
import { fs } from 'mz';
import { promises as fs } from 'fs';
import * as nock from 'nock';
import * as path from 'path';
@ -191,7 +191,9 @@ export async function runCommand(cmd: string): Promise<TestOutput> {
`The standalone tests require Node.js >= v10.16.0 because of net/proxy features ('global-agent' npm package)`,
);
}
if (!(await fs.exists(standalonePath))) {
try {
await fs.access(standalonePath);
} catch {
throw new Error(`Standalone executable not found: "${standalonePath}"`);
}
const proxy = await import('./proxy-server');

View File

@ -16,7 +16,7 @@
*/
import { expect } from 'chai';
import { fs } from 'mz';
import { promises as fs } from 'fs';
import * as path from 'path';
import {