"git@developer.sourcefind.cn:OpenDAS/nni.git" did not exist on "e8c78bbab03fa651563e21cdf004220f29d9560a"
Unverified Commit 16fd8a21 authored by Yuge Zhang's avatar Yuge Zhang Committed by GitHub
Browse files

Add support for .nniignore (#2454)

parent 10e56560
...@@ -274,7 +274,7 @@ function countFilesRecursively(directory: string): Promise<number> { ...@@ -274,7 +274,7 @@ function countFilesRecursively(directory: string): Promise<number> {
}); });
} }
function validateFileName(fileName: string): boolean { export function validateFileName(fileName: string): boolean {
const pattern: string = '^[a-z0-9A-Z._-]+$'; const pattern: string = '^[a-z0-9A-Z._-]+$';
const validateResult = fileName.match(pattern); const validateResult = fileName.match(pattern);
if (validateResult) { if (validateResult) {
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
"child-process-promise": "^2.2.1", "child-process-promise": "^2.2.1",
"express": "^4.16.3", "express": "^4.16.3",
"express-joi-validator": "^2.0.0", "express-joi-validator": "^2.0.0",
"ignore": "^5.1.4",
"js-base64": "^2.4.9", "js-base64": "^2.4.9",
"kubernetes-client": "^6.5.0", "kubernetes-client": "^6.5.0",
"rx": "^4.1.0", "rx": "^4.1.0",
...@@ -23,6 +24,7 @@ ...@@ -23,6 +24,7 @@
"ssh2": "^0.6.1", "ssh2": "^0.6.1",
"stream-buffers": "^3.0.2", "stream-buffers": "^3.0.2",
"tail-stream": "^0.3.4", "tail-stream": "^0.3.4",
"tar": "^6.0.2",
"tree-kill": "^1.2.0", "tree-kill": "^1.2.0",
"ts-deferred": "^1.0.4", "ts-deferred": "^1.0.4",
"typescript-ioc": "^1.2.4", "typescript-ioc": "^1.2.4",
...@@ -42,6 +44,7 @@ ...@@ -42,6 +44,7 @@
"@types/sqlite3": "^3.1.3", "@types/sqlite3": "^3.1.3",
"@types/ssh2": "^0.5.35", "@types/ssh2": "^0.5.35",
"@types/stream-buffers": "^3.0.2", "@types/stream-buffers": "^3.0.2",
"@types/tar": "^4.0.3",
"@types/tmp": "^0.0.33", "@types/tmp": "^0.0.33",
"@typescript-eslint/eslint-plugin": "^2.10.0", "@typescript-eslint/eslint-plugin": "^2.10.0",
"@typescript-eslint/parser": "^2.10.0", "@typescript-eslint/parser": "^2.10.0",
......
...@@ -6,12 +6,44 @@ ...@@ -6,12 +6,44 @@
import * as cpp from 'child-process-promise'; import * as cpp from 'child-process-promise';
import * as cp from 'child_process'; import * as cp from 'child_process';
import * as fs from 'fs'; import * as fs from 'fs';
import * as os from 'os'; import ignore from 'ignore';
import * as path from 'path'; import * as path from 'path';
import * as tar from 'tar';
import { String } from 'typescript-string-operations'; import { String } from 'typescript-string-operations';
import { countFilesRecursively, getNewLine, validateFileNameRecursively } from '../../common/utils'; import { validateFileName } from '../../common/utils';
import { GPU_INFO_COLLECTOR_FORMAT_WINDOWS } from './gpuData'; import { GPU_INFO_COLLECTOR_FORMAT_WINDOWS } from './gpuData';
/**
* List all files in directory except those ignored by .nniignore.
* @param source
* @param destination
*/
export function* listDirWithIgnoredFiles(root: string, relDir: string, ignoreFiles: string[]): Iterable<string> {
let ignoreFile = undefined;
const source = path.join(root, relDir);
if (fs.existsSync(path.join(source, '.nniignore'))) {
ignoreFile = path.join(source, '.nniignore');
ignoreFiles.push(ignoreFile);
}
const ig = ignore();
ignoreFiles.forEach((i) => ig.add(fs.readFileSync(i).toString()));
for (const d of fs.readdirSync(source)) {
const entry = path.join(relDir, d);
if (ig.ignores(entry))
continue;
const entryStat = fs.statSync(path.join(root, entry));
if (entryStat.isDirectory()) {
yield entry;
yield* listDirWithIgnoredFiles(root, entry, ignoreFiles);
}
else if (entryStat.isFile())
yield entry;
}
if (ignoreFile !== undefined) {
ignoreFiles.pop();
}
}
/** /**
* Validate codeDir, calculate file count recursively under codeDir, and throw error if any rule is broken * Validate codeDir, calculate file count recursively under codeDir, and throw error if any rule is broken
* *
...@@ -19,28 +51,28 @@ import { GPU_INFO_COLLECTOR_FORMAT_WINDOWS } from './gpuData'; ...@@ -19,28 +51,28 @@ import { GPU_INFO_COLLECTOR_FORMAT_WINDOWS } from './gpuData';
* @returns file number under codeDir * @returns file number under codeDir
*/ */
export async function validateCodeDir(codeDir: string): Promise<number> { export async function validateCodeDir(codeDir: string): Promise<number> {
let fileCount: number | undefined; let fileCount: number = 0;
let fileTotalSize: number = 0;
let fileNameValid: boolean = true; let fileNameValid: boolean = true;
try { for (const relPath of listDirWithIgnoredFiles(codeDir, '', [])) {
fileCount = await countFilesRecursively(codeDir); const d = path.join(codeDir, relPath);
} catch (error) { fileCount += 1;
throw new Error(`Call count file error: ${error}`); fileTotalSize += fs.statSync(d).size;
} if (fileCount > 2000) {
try { throw new Error(`Too many files and directories (${fileCount} already scanned) in ${codeDir},`
fileNameValid = await validateFileNameRecursively(codeDir); + ` please check if it's a valid code dir`);
} catch (error) { }
throw new Error(`Validate file name error: ${error}`); if (fileTotalSize > 300 * 1024 * 1024) {
} throw new Error(`File total size too large in code dir (${fileTotalSize} bytes already scanned, exceeds 300MB).`);
}
if (fileCount !== undefined && fileCount > 1000) { fileNameValid = true;
const errMessage: string = `Too many files(${fileCount} found}) in ${codeDir},` relPath.split(path.sep).forEach(fpart => {
+ ` please check if it's a valid code dir`; if (fpart !== '' && !validateFileName(fpart))
throw new Error(errMessage); fileNameValid = false;
} });
if (!fileNameValid) {
if (!fileNameValid) { throw new Error(`Validate file name error: '${d}' is an invalid file name.`);
const errMessage: string = `File name in ${codeDir} is not valid, please check file names, only support digit number、alphabet and (.-_) in file name.`; }
throw new Error(errMessage);
} }
return fileCount; return fileCount;
...@@ -68,10 +100,16 @@ export async function execMkdir(directory: string, share: boolean = false): Prom ...@@ -68,10 +100,16 @@ export async function execMkdir(directory: string, share: boolean = false): Prom
* @param destination * @param destination
*/ */
export async function execCopydir(source: string, destination: string): Promise<void> { export async function execCopydir(source: string, destination: string): Promise<void> {
if (process.platform === 'win32') { if (!fs.existsSync(destination))
await cpp.exec(`powershell.exe Copy-Item "${source}\\*" -Destination "${destination}" -Recurse`); await fs.promises.mkdir(destination);
} else { for (const relPath of listDirWithIgnoredFiles(source, '', [])) {
await cpp.exec(`cp -r '${source}/.' '${destination}'`); const sourcePath = path.join(source, relPath);
const destPath = path.join(destination, relPath);
if (fs.statSync(sourcePath).isDirectory()) {
await fs.promises.mkdir(destPath);
} else {
await fs.promises.copyFile(sourcePath, destPath);
}
} }
return Promise.resolve(); return Promise.resolve();
...@@ -165,28 +203,19 @@ export function setEnvironmentVariable(variable: { key: string; value: string }) ...@@ -165,28 +203,19 @@ export function setEnvironmentVariable(variable: { key: string; value: string })
* @param tarPath * @param tarPath
*/ */
export async function tarAdd(tarPath: string, sourcePath: string): Promise<void> { export async function tarAdd(tarPath: string, sourcePath: string): Promise<void> {
if (process.platform === 'win32') { const fileList = [];
const tarFilePath: string = tarPath.split('\\') for (const d of listDirWithIgnoredFiles(sourcePath, '', [])) {
.join('\\\\'); fileList.push(d);
const sourceFilePath: string = sourcePath.split('\\')
.join('\\\\');
const script: string[] = [];
script.push(
`import os`,
`import tarfile`,
String.Format(`tar = tarfile.open("{0}","w:gz")\r\nroot="{1}"\r\nfor file_path,dir,files in os.walk(root):`, tarFilePath, sourceFilePath),
` for file in files:`,
` full_path = os.path.join(file_path, file)`,
` file = os.path.relpath(full_path, root)`,
` tar.add(full_path, arcname=file)`,
`tar.close()`);
await fs.promises.writeFile(path.join(os.tmpdir(), 'tar.py'), script.join(getNewLine()), { encoding: 'utf8', mode: 0o777 });
const tarScript: string = path.join(os.tmpdir(), 'tar.py');
await cpp.exec(`python ${tarScript}`);
} else {
await cpp.exec(`tar -czf ${tarPath} -C ${sourcePath} .`);
} }
tar.create(
{
gzip: true,
file: tarPath,
sync: true,
cwd: sourcePath,
},
fileList
);
return Promise.resolve(); return Promise.resolve();
} }
......
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
'use strict';
import * as assert from 'assert';
import * as chai from 'chai';
import * as fs from 'fs';
import * as path from 'path';
import * as tar from 'tar';
import { execCopydir, tarAdd, validateCodeDir } from '../common/util';
const deleteFolderRecursive = (filePath: string) => {
if (fs.existsSync(filePath)) {
fs.readdirSync(filePath).forEach((file, index) => {
const curPath = path.join(filePath, file);
if (fs.lstatSync(curPath).isDirectory()) { // recurse
deleteFolderRecursive(curPath);
} else { // delete file
fs.unlinkSync(curPath);
}
});
fs.rmdirSync(filePath);
}
};
describe('fileUtility', () => {
/*
Test file utilities, includes:
- Copy directory
- Ignore with ignore file
- Add to tar
*/
const sourceDir = 'test-fileUtilityTestSource';
const destDir = 'test-fileUtilityTestDest';
beforeEach(() => {
fs.mkdirSync(sourceDir);
fs.writeFileSync(path.join(sourceDir, '.nniignore'), 'abc\nxyz');
fs.writeFileSync(path.join(sourceDir, 'abc'), '123');
fs.writeFileSync(path.join(sourceDir, 'abcd'), '1234');
fs.mkdirSync(path.join(sourceDir, 'xyz'));
fs.mkdirSync(path.join(sourceDir, 'xyy'));
fs.mkdirSync(path.join(sourceDir, 'www'));
fs.mkdirSync(path.join(sourceDir, 'xx')); // empty dir
fs.writeFileSync(path.join(sourceDir, 'xyy', '.nniignore'), 'qq'); // nested nniignore
fs.writeFileSync(path.join(sourceDir, 'xyy', 'abc'), '123');
fs.writeFileSync(path.join(sourceDir, 'xyy', 'qq'), '1234');
fs.writeFileSync(path.join(sourceDir, 'xyy', 'pp'), '1234');
fs.writeFileSync(path.join(sourceDir, 'www', '.nniignore'), 'pp'); // pop nniignore
fs.writeFileSync(path.join(sourceDir, 'www', 'abc'), '123');
fs.writeFileSync(path.join(sourceDir, 'www', 'qq'), '1234');
fs.writeFileSync(path.join(sourceDir, 'www', 'pp'), '1234');
});
afterEach(() => {
deleteFolderRecursive(sourceDir);
deleteFolderRecursive(destDir);
if (fs.existsSync(`${destDir}.tar`)) {
fs.unlinkSync(`${destDir}.tar`);
}
});
it('Test file copy', async () => {
await execCopydir(sourceDir, destDir);
const existFiles = [
'abcd',
'xyy',
'xx',
path.join('xyy', '.nniignore'),
path.join('xyy', 'pp'),
path.join('www', '.nniignore'),
path.join('www', 'qq'),
]
const notExistFiles = [
'abc',
'xyz',
path.join('xyy', 'abc'),
path.join('xyy', 'qq'),
path.join('www', 'pp'),
path.join('www', 'abc'),
]
existFiles.forEach(d => assert.ok(fs.existsSync(path.join(destDir, d))));
notExistFiles.forEach(d => assert.ok(!fs.existsSync(path.join(destDir, d))));
});
it('Test file copy without ignore', async () => {
fs.unlinkSync(path.join(sourceDir, '.nniignore'));
await execCopydir(sourceDir, destDir);
assert.ok(fs.existsSync(path.join(destDir, 'abcd')));
assert.ok(fs.existsSync(path.join(destDir, 'abc')));
assert.ok(fs.existsSync(path.join(destDir, 'xyz')));
assert.ok(fs.existsSync(path.join(destDir, 'xyy')));
assert.ok(fs.existsSync(path.join(destDir, 'xx')));
});
it('Test tar file', async () => {
const tarPath = `${destDir}.tar`;
await tarAdd(tarPath, sourceDir);
assert.ok(fs.existsSync(tarPath));
fs.mkdirSync(destDir);
tar.extract({
file: tarPath,
cwd: destDir,
sync: true
})
assert.ok(fs.existsSync(path.join(destDir, 'abcd')));
assert.ok(!fs.existsSync(path.join(destDir, 'abc')));
});
it('Validate code ok', async () => {
assert.doesNotThrow(async () => validateCodeDir(sourceDir));
});
it('Validate code too many files', async () => {
for (let i = 0; i < 2000; ++i)
fs.writeFileSync(path.join(sourceDir, `${i}.txt`), 'a');
try {
await validateCodeDir(sourceDir);
} catch (error) {
chai.expect(error.message).to.contains('many files');
return;
}
chai.expect.fail(null, null, 'Did not fail.');
});
it('Validate code too many files ok', async() => {
for (let i = 0; i < 2000; ++i)
fs.writeFileSync(path.join(sourceDir, `${i}.txt`), 'a');
fs.writeFileSync(path.join(sourceDir, '.nniignore'), '*.txt');
assert.doesNotThrow(async () => validateCodeDir(sourceDir));
});
});
...@@ -296,6 +296,13 @@ ...@@ -296,6 +296,13 @@
version "3.0.3" version "3.0.3"
resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"
"@types/minipass@*":
version "2.2.0"
resolved "https://registry.yarnpkg.com/@types/minipass/-/minipass-2.2.0.tgz#51ad404e8eb1fa961f75ec61205796807b6f9651"
integrity sha512-wuzZksN4w4kyfoOv/dlpov4NOunwutLA/q7uc00xU02ZyUY+aoM5PWIXEKBMnm0NHd4a+N71BMjq+x7+2Af1fg==
dependencies:
"@types/node" "*"
"@types/mocha@^5.2.5": "@types/mocha@^5.2.5":
version "5.2.5" version "5.2.5"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.5.tgz#8a4accfc403c124a0bafe8a9fc61a05ec1032073" resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.5.tgz#8a4accfc403c124a0bafe8a9fc61a05ec1032073"
...@@ -442,6 +449,14 @@ ...@@ -442,6 +449,14 @@
dependencies: dependencies:
"@types/node" "*" "@types/node" "*"
"@types/tar@^4.0.3":
version "4.0.3"
resolved "https://registry.yarnpkg.com/@types/tar/-/tar-4.0.3.tgz#e2cce0b8ff4f285293243f5971bd7199176ac489"
integrity sha512-Z7AVMMlkI8NTWF0qGhC4QIX0zkV/+y0J8x7b/RsHrN0310+YNjoJd8UrApCiGBCWtKjxS9QhNqLi2UJNToh5hA==
dependencies:
"@types/minipass" "*"
"@types/node" "*"
"@types/tmp@^0.0.33": "@types/tmp@^0.0.33":
version "0.0.33" version "0.0.33"
resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.0.33.tgz#1073c4bc824754ae3d10cfab88ab0237ba964e4d" resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.0.33.tgz#1073c4bc824754ae3d10cfab88ab0237ba964e4d"
...@@ -992,6 +1007,11 @@ chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.3: ...@@ -992,6 +1007,11 @@ chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.3:
version "1.1.3" version "1.1.3"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142"
chownr@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/chownr/-/chownr-2.0.0.tgz#15bfbe53d2eab4cf70f18a8cd68ebe5b3cb1dece"
integrity sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==
ci-info@^1.5.0: ci-info@^1.5.0:
version "1.6.0" version "1.6.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497" resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
...@@ -1880,6 +1900,13 @@ fs-minipass@^1.2.5: ...@@ -1880,6 +1900,13 @@ fs-minipass@^1.2.5:
dependencies: dependencies:
minipass "^2.2.1" minipass "^2.2.1"
fs-minipass@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-2.1.0.tgz#7f5036fdbf12c63c169190cbe4199c852271f9fb"
integrity sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==
dependencies:
minipass "^3.0.0"
fs-vacuum@^1.2.10, fs-vacuum@~1.2.10: fs-vacuum@^1.2.10, fs-vacuum@~1.2.10:
version "1.2.10" version "1.2.10"
resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36" resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36"
...@@ -2282,6 +2309,11 @@ ignore@^4.0.6: ...@@ -2282,6 +2309,11 @@ ignore@^4.0.6:
version "4.0.6" version "4.0.6"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc" resolved "https://registry.yarnpkg.com/ignore/-/ignore-4.0.6.tgz#750e3db5862087b4737ebac8207ffd1ef27b25fc"
ignore@^5.1.4:
version "5.1.4"
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf"
integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==
import-fresh@^3.0.0: import-fresh@^3.0.0:
version "3.2.1" version "3.2.1"
resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66"
...@@ -2605,10 +2637,10 @@ istanbul-lib-source-maps@^4.0.0: ...@@ -2605,10 +2637,10 @@ istanbul-lib-source-maps@^4.0.0:
istanbul-lib-coverage "^3.0.0" istanbul-lib-coverage "^3.0.0"
source-map "^0.6.1" source-map "^0.6.1"
istanbul-reports@^3.0.0: istanbul-reports@^3.0.2:
version "3.0.1" version "3.0.2"
resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.1.tgz#1343217244ad637e0c3b18e7f6b746941a9b5e9a" resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.2.tgz#d593210e5000683750cb09fc0644e4b6e27fd53b"
integrity sha512-Vm9xwCiQ8t2cNNnckyeAV0UdxKpcQUz4nMxsBvIu8n2kmPSiyb5uaF/8LpmKr+yqL/MdOXaX2Nmdo4Qyxium9Q== integrity sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==
dependencies: dependencies:
html-escaper "^2.0.0" html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0" istanbul-lib-report "^3.0.0"
...@@ -3154,6 +3186,13 @@ minipass@^2.3.5, minipass@^2.8.6, minipass@^2.9.0: ...@@ -3154,6 +3186,13 @@ minipass@^2.3.5, minipass@^2.8.6, minipass@^2.9.0:
safe-buffer "^5.1.2" safe-buffer "^5.1.2"
yallist "^3.0.0" yallist "^3.0.0"
minipass@^3.0.0:
version "3.1.3"
resolved "https://registry.yarnpkg.com/minipass/-/minipass-3.1.3.tgz#7d42ff1f39635482e15f9cdb53184deebd5815fd"
integrity sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==
dependencies:
yallist "^4.0.0"
minizlib@^1.1.0: minizlib@^1.1.0:
version "1.1.0" version "1.1.0"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb"
...@@ -3166,6 +3205,14 @@ minizlib@^1.2.1: ...@@ -3166,6 +3205,14 @@ minizlib@^1.2.1:
dependencies: dependencies:
minipass "^2.9.0" minipass "^2.9.0"
minizlib@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-2.1.0.tgz#fd52c645301ef09a63a2c209697c294c6ce02cf3"
integrity sha512-EzTZN/fjSvifSX0SlqUERCN39o6T40AMarPbv0MrarSFtIITCBh7bi+dU8nxGFHuqs9jdIAeoYoKuQAAASsPPA==
dependencies:
minipass "^3.0.0"
yallist "^4.0.0"
mississippi@^3.0.0: mississippi@^3.0.0:
version "3.0.0" version "3.0.0"
resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022" resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-3.0.0.tgz#ea0a3291f97e0b5e8776b363d5f0a12d94c67022"
...@@ -3188,6 +3235,11 @@ mkdirp@0.5.3, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: ...@@ -3188,6 +3235,11 @@ mkdirp@0.5.3, mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
dependencies: dependencies:
minimist "^1.2.5" minimist "^1.2.5"
mkdirp@^1.0.3:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
mocha@^7.1.1: mocha@^7.1.1:
version "7.1.1" version "7.1.1"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.1.tgz#89fbb30d09429845b1bb893a830bf5771049a441" resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.1.tgz#89fbb30d09429845b1bb893a830bf5771049a441"
...@@ -3344,7 +3396,7 @@ node-pre-gyp@^0.10.3: ...@@ -3344,7 +3396,7 @@ node-pre-gyp@^0.10.3:
semver "^5.3.0" semver "^5.3.0"
tar "^4" tar "^4"
node-preload@^0.2.0: node-preload@^0.2.1:
version "0.2.1" version "0.2.1"
resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301" resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301"
integrity sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ== integrity sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==
...@@ -3641,9 +3693,9 @@ number-is-nan@^1.0.0: ...@@ -3641,9 +3693,9 @@ number-is-nan@^1.0.0:
resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d"
nyc@^15.0.0: nyc@^15.0.0:
version "15.0.0" version "15.0.1"
resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.0.0.tgz#eb32db2c0f29242c2414fe46357f230121cfc162" resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.0.1.tgz#bd4d5c2b17f2ec04370365a5ca1fc0ed26f9f93d"
integrity sha512-qcLBlNCKMDVuKb7d1fpxjPR8sHeMVX0CHarXAVzrVWoFrigCkYR8xcrjfXSPi5HXM7EU78L6ywO7w1c5rZNCNg== integrity sha512-n0MBXYBYRqa67IVt62qW1r/d9UH/Qtr7SF1w/nQLJ9KxvWF6b2xCHImRAixHN9tnMMYHC2P14uo6KddNGwMgGg==
dependencies: dependencies:
"@istanbuljs/load-nyc-config" "^1.0.0" "@istanbuljs/load-nyc-config" "^1.0.0"
"@istanbuljs/schema" "^0.1.2" "@istanbuljs/schema" "^0.1.2"
...@@ -3660,10 +3712,9 @@ nyc@^15.0.0: ...@@ -3660,10 +3712,9 @@ nyc@^15.0.0:
istanbul-lib-processinfo "^2.0.2" istanbul-lib-processinfo "^2.0.2"
istanbul-lib-report "^3.0.0" istanbul-lib-report "^3.0.0"
istanbul-lib-source-maps "^4.0.0" istanbul-lib-source-maps "^4.0.0"
istanbul-reports "^3.0.0" istanbul-reports "^3.0.2"
js-yaml "^3.13.1"
make-dir "^3.0.0" make-dir "^3.0.0"
node-preload "^0.2.0" node-preload "^0.2.1"
p-map "^3.0.0" p-map "^3.0.0"
process-on-spawn "^1.0.0" process-on-spawn "^1.0.0"
resolve-from "^5.0.0" resolve-from "^5.0.0"
...@@ -3671,7 +3722,6 @@ nyc@^15.0.0: ...@@ -3671,7 +3722,6 @@ nyc@^15.0.0:
signal-exit "^3.0.2" signal-exit "^3.0.2"
spawn-wrap "^2.0.0" spawn-wrap "^2.0.0"
test-exclude "^6.0.0" test-exclude "^6.0.0"
uuid "^3.3.3"
yargs "^15.0.2" yargs "^15.0.2"
oauth-sign@~0.8.2: oauth-sign@~0.8.2:
...@@ -4980,6 +5030,18 @@ tar@^4.4.10, tar@^4.4.12, tar@^4.4.13: ...@@ -4980,6 +5030,18 @@ tar@^4.4.10, tar@^4.4.12, tar@^4.4.13:
safe-buffer "^5.1.2" safe-buffer "^5.1.2"
yallist "^3.0.3" yallist "^3.0.3"
tar@^6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/tar/-/tar-6.0.2.tgz#5df17813468a6264ff14f766886c622b84ae2f39"
integrity sha512-Glo3jkRtPcvpDlAs/0+hozav78yoXKFr+c4wgw62NNMO3oo4AaJdCo21Uu7lcwr55h39W2XD1LMERc64wtbItg==
dependencies:
chownr "^2.0.0"
fs-minipass "^2.0.0"
minipass "^3.0.0"
minizlib "^2.1.0"
mkdirp "^1.0.3"
yallist "^4.0.0"
term-size@^1.2.0: term-size@^1.2.0:
version "1.2.0" version "1.2.0"
resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69" resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69"
...@@ -5438,6 +5500,11 @@ yallist@^3.0.3: ...@@ -5438,6 +5500,11 @@ yallist@^3.0.3:
version "3.1.1" version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
yallist@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72"
integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==
yargs-parser@13.1.2, yargs-parser@^13.1.2: yargs-parser@13.1.2, yargs-parser@^13.1.2:
version "13.1.2" version "13.1.2"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment