Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
OpenDAS
nni
Commits
16fd8a21
Unverified
Commit
16fd8a21
authored
Jun 19, 2020
by
Yuge Zhang
Committed by
GitHub
Jun 19, 2020
Browse files
Add support for .nniignore (#2454)
parent
10e56560
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
293 additions
and
61 deletions
+293
-61
src/nni_manager/common/utils.ts
src/nni_manager/common/utils.ts
+1
-1
src/nni_manager/package.json
src/nni_manager/package.json
+3
-0
src/nni_manager/training_service/common/util.ts
src/nni_manager/training_service/common/util.ts
+77
-48
src/nni_manager/training_service/test/fileUtility.test.ts
src/nni_manager/training_service/test/fileUtility.test.ts
+133
-0
src/nni_manager/yarn.lock
src/nni_manager/yarn.lock
+79
-12
No files found.
src/nni_manager/common/utils.ts
View file @
16fd8a21
...
...
@@ -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
validateResult
=
fileName
.
match
(
pattern
);
if
(
validateResult
)
{
...
...
src/nni_manager/package.json
View file @
16fd8a21
...
...
@@ -16,6 +16,7 @@
"child-process-promise"
:
"^2.2.1"
,
"express"
:
"^4.16.3"
,
"express-joi-validator"
:
"^2.0.0"
,
"ignore"
:
"^5.1.4"
,
"js-base64"
:
"^2.4.9"
,
"kubernetes-client"
:
"^6.5.0"
,
"rx"
:
"^4.1.0"
,
...
...
@@ -23,6 +24,7 @@
"ssh2"
:
"^0.6.1"
,
"stream-buffers"
:
"^3.0.2"
,
"tail-stream"
:
"^0.3.4"
,
"tar"
:
"^6.0.2"
,
"tree-kill"
:
"^1.2.0"
,
"ts-deferred"
:
"^1.0.4"
,
"typescript-ioc"
:
"^1.2.4"
,
...
...
@@ -42,6 +44,7 @@
"@types/sqlite3"
:
"^3.1.3"
,
"@types/ssh2"
:
"^0.5.35"
,
"@types/stream-buffers"
:
"^3.0.2"
,
"@types/tar"
:
"^4.0.3"
,
"@types/tmp"
:
"^0.0.33"
,
"@typescript-eslint/eslint-plugin"
:
"^2.10.0"
,
"@typescript-eslint/parser"
:
"^2.10.0"
,
...
...
src/nni_manager/training_service/common/util.ts
View file @
16fd8a21
...
...
@@ -6,12 +6,44 @@
import
*
as
cpp
from
'
child-process-promise
'
;
import
*
as
cp
from
'
child_process
'
;
import
*
as
fs
from
'
fs
'
;
import
*
as
os
from
'
os
'
;
import
ignore
from
'
ignore
'
;
import
*
as
path
from
'
path
'
;
import
*
as
tar
from
'
tar
'
;
import
{
String
}
from
'
typescript-string-operations
'
;
import
{
countFilesRecursively
,
getNewLine
,
validateFileName
Recursively
}
from
'
../../common/utils
'
;
import
{
validateFileName
}
from
'
../../common/utils
'
;
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
*
...
...
@@ -19,28 +51,28 @@ import { GPU_INFO_COLLECTOR_FORMAT_WINDOWS } from './gpuData';
* @returns file number under codeDir
*/
export
async
function
validateCodeDir
(
codeDir
:
string
):
Promise
<
number
>
{
let
fileCount
:
number
|
undefined
;
let
fileCount
:
number
=
0
;
let
fileTotalSize
:
number
=
0
;
let
fileNameValid
:
boolean
=
true
;
try
{
fileCount
=
await
countFilesRecursively
(
codeDir
);
}
catch
(
error
)
{
throw
new
Error
(
`Call count file error:
${
error
}
`
);
for
(
const
relPath
of
listDirWithIgnoredFiles
(
codeDir
,
''
,
[]))
{
const
d
=
path
.
join
(
codeDir
,
relPath
);
fileCount
+=
1
;
fileTotalSize
+=
fs
.
statSync
(
d
).
size
;
if
(
fileCount
>
2000
)
{
throw
new
Error
(
`Too many files and directories (
${
fileCount
}
already scanned) in
${
codeDir
}
,`
+
` please check if it's a valid code dir`
);
}
try
{
fileNameValid
=
await
validateFileNameRecursively
(
codeDir
);
}
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
)
{
const
errMessage
:
string
=
`Too many files(
${
fileCount
}
found}) in
${
codeDir
}
,`
+
` please check if it's a valid code dir`
;
throw
new
Error
(
errMessage
);
}
fileNameValid
=
true
;
relPath
.
split
(
path
.
sep
).
forEach
(
fpart
=>
{
if
(
fpart
!==
''
&&
!
validateFileName
(
fpart
))
fileNameValid
=
false
;
});
if
(
!
fileNameValid
)
{
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
);
throw
new
Error
(
`Validate file name error: '
${
d
}
' is an invalid
file name.`
)
;
}
}
return
fileCount
;
...
...
@@ -68,10 +100,16 @@ export async function execMkdir(directory: string, share: boolean = false): Prom
* @param destination
*/
export
async
function
execCopydir
(
source
:
string
,
destination
:
string
):
Promise
<
void
>
{
if
(
process
.
platform
===
'
win32
'
)
{
await
cpp
.
exec
(
`powershell.exe Copy-Item "
${
source
}
\\*" -Destination "
${
destination
}
" -Recurse`
);
if
(
!
fs
.
existsSync
(
destination
))
await
fs
.
promises
.
mkdir
(
destination
);
for
(
const
relPath
of
listDirWithIgnoredFiles
(
source
,
''
,
[]))
{
const
sourcePath
=
path
.
join
(
source
,
relPath
);
const
destPath
=
path
.
join
(
destination
,
relPath
);
if
(
fs
.
statSync
(
sourcePath
).
isDirectory
())
{
await
fs
.
promises
.
mkdir
(
destPath
);
}
else
{
await
cpp
.
exec
(
`cp -r '
${
source
}
/.' '
${
destination
}
'`
);
await
fs
.
promises
.
copyFile
(
sourcePath
,
destPath
);
}
}
return
Promise
.
resolve
();
...
...
@@ -165,28 +203,19 @@ export function setEnvironmentVariable(variable: { key: string; value: string })
* @param tarPath
*/
export
async
function
tarAdd
(
tarPath
:
string
,
sourcePath
:
string
):
Promise
<
void
>
{
if
(
process
.
platform
===
'
win32
'
)
{
const
tarFilePath
:
string
=
tarPath
.
split
(
'
\\
'
)
.
join
(
'
\\\\
'
);
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
}
.`
);
const
fileList
=
[];
for
(
const
d
of
listDirWithIgnoredFiles
(
sourcePath
,
''
,
[]))
{
fileList
.
push
(
d
);
}
tar
.
create
(
{
gzip
:
true
,
file
:
tarPath
,
sync
:
true
,
cwd
:
sourcePath
,
},
fileList
);
return
Promise
.
resolve
();
}
...
...
src/nni_manager/training_service/test/fileUtility.test.ts
0 → 100644
View file @
16fd8a21
// 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
\n
xyz
'
);
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
));
});
});
src/nni_manager/yarn.lock
View file @
16fd8a21
...
...
@@ -296,6 +296,13 @@
version "3.0.3"
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":
version "5.2.5"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-5.2.5.tgz#8a4accfc403c124a0bafe8a9fc61a05ec1032073"
...
...
@@ -442,6 +449,14 @@
dependencies:
"@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":
version "0.0.33"
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:
version "1.1.3"
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:
version "1.6.0"
resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.6.0.tgz#2ca20dbb9ceb32d4524a683303313f0304b1e497"
...
...
@@ -1880,6 +1900,13 @@ fs-minipass@^1.2.5:
dependencies:
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:
version "1.2.10"
resolved "https://registry.yarnpkg.com/fs-vacuum/-/fs-vacuum-1.2.10.tgz#b7629bec07a4031a2548fdf99f5ecf1cc8b31e36"
...
...
@@ -2282,6 +2309,11 @@ ignore@^4.0.6:
version "4.0.6"
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:
version "3.2.1"
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:
istanbul-lib-coverage "^3.0.0"
source-map "^0.6.1"
istanbul-reports@^3.0.
0
:
version "3.0.
1
"
resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.
1
.tgz#
1343217244ad6
37
e
0c
3b18e7f6b746941a9b5e9a
"
integrity sha512-
Vm9xwCiQ8t2cNNnckyeAV0UdxKpcQUz4nMxsBvIu8n2kmPSiyb5uaF/8LpmKr+yqL/MdOXaX2Nmdo4Qyxium9Q
==
istanbul-reports@^3.0.
2
:
version "3.0.
2
"
resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-3.0.
2
.tgz#
d593210e500068
37
5
0c
b09fc0644e4b6e27fd53b
"
integrity sha512-
9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw
==
dependencies:
html-escaper "^2.0.0"
istanbul-lib-report "^3.0.0"
...
...
@@ -3154,6 +3186,13 @@ minipass@^2.3.5, minipass@^2.8.6, minipass@^2.9.0:
safe-buffer "^5.1.2"
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:
version "1.1.0"
resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb"
...
...
@@ -3166,6 +3205,14 @@ minizlib@^1.2.1:
dependencies:
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:
version "3.0.0"
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:
dependencies:
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:
version "7.1.1"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-7.1.1.tgz#89fbb30d09429845b1bb893a830bf5771049a441"
...
...
@@ -3344,7 +3396,7 @@ node-pre-gyp@^0.10.3:
semver "^5.3.0"
tar "^4"
node-preload@^0.2.
0
:
node-preload@^0.2.
1
:
version "0.2.1"
resolved "https://registry.yarnpkg.com/node-preload/-/node-preload-0.2.1.tgz#c03043bb327f417a18fee7ab7ee57b408a144301"
integrity sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==
...
...
@@ -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"
nyc@^15.0.0:
version "15.0.
0
"
resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.0.
0
.tgz#
eb32db2c0f29242c2414fe46357f230121cfc162
"
integrity sha512-
qcLBlNCKMDVuKb7d1fpxjPR8sHeMVX0CHarXAVzrVWoFrigCkYR8xcrjfXSPi5HXM7EU78L6ywO7w1c5rZNCN
g==
version "15.0.
1
"
resolved "https://registry.yarnpkg.com/nyc/-/nyc-15.0.
1
.tgz#
bd4d5c2b17f2ec04370365a5ca1fc0ed26f9f93d
"
integrity sha512-
n0MBXYBYRqa67IVt62qW1r/d9UH/Qtr7SF1w/nQLJ9KxvWF6b2xCHImRAixHN9tnMMYHC2P14uo6KddNGwMgG
g==
dependencies:
"@istanbuljs/load-nyc-config" "^1.0.0"
"@istanbuljs/schema" "^0.1.2"
...
...
@@ -3660,10 +3712,9 @@ nyc@^15.0.0:
istanbul-lib-processinfo "^2.0.2"
istanbul-lib-report "^3.0.0"
istanbul-lib-source-maps "^4.0.0"
istanbul-reports "^3.0.0"
js-yaml "^3.13.1"
istanbul-reports "^3.0.2"
make-dir "^3.0.0"
node-preload "^0.2.
0
"
node-preload "^0.2.
1
"
p-map "^3.0.0"
process-on-spawn "^1.0.0"
resolve-from "^5.0.0"
...
...
@@ -3671,7 +3722,6 @@ nyc@^15.0.0:
signal-exit "^3.0.2"
spawn-wrap "^2.0.0"
test-exclude "^6.0.0"
uuid "^3.3.3"
yargs "^15.0.2"
oauth-sign@~0.8.2:
...
...
@@ -4980,6 +5030,18 @@ tar@^4.4.10, tar@^4.4.12, tar@^4.4.13:
safe-buffer "^5.1.2"
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:
version "1.2.0"
resolved "https://registry.yarnpkg.com/term-size/-/term-size-1.2.0.tgz#458b83887f288fc56d6fffbfad262e26638efa69"
...
...
@@ -5438,6 +5500,11 @@ yallist@^3.0.3:
version "3.1.1"
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:
version "13.1.2"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38"
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment