Merge pull request #1620 from nagilson/nagilson-linux-single-prompt
Reduce Linux Prompt to Single Ask
This commit is contained in:
Коммит
cd362f67ba
|
@ -9,6 +9,7 @@
|
|||
"HKCU",
|
||||
"HKEY",
|
||||
"norestart",
|
||||
"proccom",
|
||||
"programfiles",
|
||||
"REGHEXVALUE",
|
||||
"REGTYPE"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
# The library doesn't get webpacked, but it needs the copy of items that would normally be webpacked
|
||||
# ... into the SDK or Runtime Extension for it to run in local dev scenarios.
|
||||
Copy-Item ".\vscode-dotnet-runtime-library\distro-data\" -Destination ".\vscode-dotnet-runtime-library\dist\Acquisition\" -Recurse -Force
|
||||
Copy-Item ".\vscode-dotnet-runtime-library\install scripts\" -Destination ".\vscode-dotnet-runtime-library\dist\utils\" -Recurse -Force
|
||||
|
|
|
@ -2,3 +2,4 @@ echo ""
|
|||
echo "----------- Copying Library Webpacked Dependencies -----------"
|
||||
echo "" # See the build.ps1 for more details on why we do this
|
||||
cp -r ./vscode-dotnet-runtime-library/distro-data ./vscode-dotnet-runtime-library/dist/Acquisition
|
||||
cp -r "./vscode-dotnet-runtime-library/install scripts" ./vscode-dotnet-runtime-library/dist/Utils
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
"version": "2.0.1",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/chai-as-promised": "^7.1.8",
|
||||
"axios": "^1.3.4",
|
||||
"axios-cache-interceptor": "^1.0.1",
|
||||
"axios-retry": "^3.4.0",
|
||||
|
@ -24,6 +25,7 @@
|
|||
"open": "^8.4.0",
|
||||
"public-ip": "5.0.0",
|
||||
"rimraf": "3.0.2",
|
||||
"safe-array-concat": "^1.1.0",
|
||||
"safe-regex-test": "^1.0.0",
|
||||
"shelljs": "^0.8.5",
|
||||
"ts-loader": "^9.2.6",
|
||||
|
@ -31,6 +33,7 @@
|
|||
"typescript": "4.4.4",
|
||||
"vscode-dotnet-runtime-library": "file:../vscode-dotnet-runtime-library",
|
||||
"vscode-test": "^1.6.1",
|
||||
"webpack-permissions-plugin": "^1.0.9",
|
||||
"yarn": "^1.22.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -377,9 +380,17 @@
|
|||
"version": "4.3.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/chai/-/chai-4.3.5.tgz",
|
||||
"integrity": "sha1-rmm8uxvrtoxKwLEenY7QRSazVis=",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/chai-as-promised": {
|
||||
"version": "7.1.8",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz",
|
||||
"integrity": "sha1-8rPYLVPFlia11rvAh2Z8y0tnf+k=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/chai": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/eslint": {
|
||||
"version": "8.4.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/eslint/-/eslint-8.4.5.tgz",
|
||||
|
@ -1000,13 +1011,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/call-bind": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/call-bind/-/call-bind-1.0.2.tgz",
|
||||
"integrity": "sha1-sdTonmiBGcPJqQOtMKuy9qkZvjw=",
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/call-bind/-/call-bind-1.0.5.tgz",
|
||||
"integrity": "sha1-b6K3hFzg6km/TYue9kcnosLi5RM=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1",
|
||||
"get-intrinsic": "^1.0.2"
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.1",
|
||||
"set-function-length": "^1.1.1"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
|
@ -1380,6 +1392,20 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/define-data-property": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/define-data-property/-/define-data-property-1.1.1.tgz",
|
||||
"integrity": "sha1-w1980KsJiDSA0SrFyyE3FVh4ALM=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.2.1",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/define-lazy-prop": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
|
||||
|
@ -1506,6 +1532,12 @@
|
|||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/err-code": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/err-code/-/err-code-1.1.2.tgz",
|
||||
"integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/es-module-lexer": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/es-module-lexer/-/es-module-lexer-1.3.0.tgz",
|
||||
|
@ -1635,6 +1667,12 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo=",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
|
@ -1700,6 +1738,58 @@
|
|||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/file-js": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/file-js/-/file-js-0.3.0.tgz",
|
||||
"integrity": "sha1-+rRr94I0bJKUSZ8fDSrQfYOPJdE=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bluebird": "^3.4.7",
|
||||
"minimatch": "^3.0.3",
|
||||
"proper-lockfile": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/filehound": {
|
||||
"version": "1.17.6",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/filehound/-/filehound-1.17.6.tgz",
|
||||
"integrity": "sha1-1dh71pQxbqZzvQZCt3a1CNP5ih0=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"bluebird": "^3.7.2",
|
||||
"file-js": "0.3.0",
|
||||
"lodash": "^4.17.21",
|
||||
"minimatch": "^5.0.0",
|
||||
"moment": "^2.29.1",
|
||||
"unit-compare": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/filehound/node_modules/bluebird": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/bluebird/-/bluebird-3.7.2.tgz",
|
||||
"integrity": "sha1-nyKcFb4nJFT/qXOs4NvueaGww28=",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/filehound/node_modules/brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha1-HtxFng8MVISG7Pn8mfIiE2S5oK4=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/filehound/node_modules/minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha1-HPy4z1Ui6mmVLNKvla4JR38SKpY=",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/fill-range/-/fill-range-7.0.1.tgz",
|
||||
|
@ -1827,10 +1917,13 @@
|
|||
}
|
||||
},
|
||||
"node_modules/function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=",
|
||||
"license": "MIT"
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha1-LALYZNl/PqbIgwxGTL0Rq26rehw=",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
|
@ -1851,14 +1944,15 @@
|
|||
}
|
||||
},
|
||||
"node_modules/get-intrinsic": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
|
||||
"integrity": "sha1-BjyEMprZPoOJPH9PJD72P/o1E4U=",
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
|
||||
"integrity": "sha1-KBt2IpcRI+HvSzyQ/XU5MG2pPzs=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"has-symbols": "^1.0.3"
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
|
@ -1939,6 +2033,18 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/gopd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/gopd/-/gopd-1.0.1.tgz",
|
||||
"integrity": "sha1-Kf923mnax0ibfAkYpXiOVkd8Myw=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.1.3"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/got": {
|
||||
"version": "11.8.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/got/-/got-11.8.5.tgz",
|
||||
|
@ -2000,6 +2106,30 @@
|
|||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/has-property-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-UrowtsXsh/2J+ldLwcORJcb2U0A=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"get-intrinsic": "^1.2.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-proto/-/has-proto-1.0.1.tgz",
|
||||
"integrity": "sha1-GIXBMFU4lYr/Rp/vN5N8InlUCOA=",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
|
@ -2037,6 +2167,18 @@
|
|||
"minimalistic-assert": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/hasown": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/hasown/-/hasown-2.0.0.tgz",
|
||||
"integrity": "sha1-9MUT1FSle3x+FlB3jeImsRcAVGw=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"function-bind": "^1.1.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/he": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/he/-/he-1.2.0.tgz",
|
||||
|
@ -2705,6 +2847,12 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw=",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/log-symbols": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/log-symbols/-/log-symbols-4.1.0.tgz",
|
||||
|
@ -2949,6 +3097,15 @@
|
|||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/moment": {
|
||||
"version": "2.30.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/moment/-/moment-2.30.1.tgz",
|
||||
"integrity": "sha1-+MkcB7enhuMMWZJt9TC06slpdK4=",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ms/-/ms-2.1.3.tgz",
|
||||
|
@ -3318,6 +3475,18 @@
|
|||
"integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I=",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/proper-lockfile": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/proper-lockfile/-/proper-lockfile-1.2.0.tgz",
|
||||
"integrity": "sha1-zv9d2J0+XxD7deHo52vHWAGlnDQ=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"err-code": "^1.0.0",
|
||||
"extend": "^3.0.0",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"retry": "^0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
|
@ -3677,6 +3846,15 @@
|
|||
"lowercase-keys": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/retry": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/retry/-/retry-0.10.1.tgz",
|
||||
"integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/reusify/-/reusify-1.0.4.tgz",
|
||||
|
@ -3727,6 +3905,30 @@
|
|||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-array-concat": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/safe-array-concat/-/safe-array-concat-1.1.0.tgz",
|
||||
"integrity": "sha1-jQyunLgG1tHAbgirE9hHKT6+BpI=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"call-bind": "^1.0.5",
|
||||
"get-intrinsic": "^1.2.2",
|
||||
"has-symbols": "^1.0.3",
|
||||
"isarray": "^2.0.5"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=0.4"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/safe-array-concat/node_modules/isarray": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/isarray/-/isarray-2.0.5.tgz",
|
||||
"integrity": "sha1-ivHkwSISRMxiRZ+vOJQNTmRKVyM=",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
@ -3797,6 +3999,22 @@
|
|||
"randombytes": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/set-function-length": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/set-function-length/-/set-function-length-1.2.0.tgz",
|
||||
"integrity": "sha1-L4HcbBbHBZvaWrfILBHwOlFe2OE=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"define-data-property": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.2",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/setimmediate": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||
|
@ -4291,6 +4509,15 @@
|
|||
"node": ">=4.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/unit-compare": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/unit-compare/-/unit-compare-1.0.1.tgz",
|
||||
"integrity": "sha1-DHRZ8OW/U2N+qHPKPO4Y3i7so4Y=",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"moment": "^2.14.1"
|
||||
}
|
||||
},
|
||||
"node_modules/unzipper": {
|
||||
"version": "0.10.11",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/unzipper/-/unzipper-0.10.11.tgz",
|
||||
|
@ -4584,6 +4811,15 @@
|
|||
"node": ">=10.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-permissions-plugin": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/webpack-permissions-plugin/-/webpack-permissions-plugin-1.0.9.tgz",
|
||||
"integrity": "sha1-gK5aCe0ZkdvbL5/kYYuNVxlhbh4=",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"filehound": "^1.17.6"
|
||||
}
|
||||
},
|
||||
"node_modules/webpack-sources": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
||||
|
@ -4923,8 +5159,15 @@
|
|||
"@types/chai": {
|
||||
"version": "4.3.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/chai/-/chai-4.3.5.tgz",
|
||||
"integrity": "sha1-rmm8uxvrtoxKwLEenY7QRSazVis=",
|
||||
"dev": true
|
||||
"integrity": "sha1-rmm8uxvrtoxKwLEenY7QRSazVis="
|
||||
},
|
||||
"@types/chai-as-promised": {
|
||||
"version": "7.1.8",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz",
|
||||
"integrity": "sha1-8rPYLVPFlia11rvAh2Z8y0tnf+k=",
|
||||
"requires": {
|
||||
"@types/chai": "*"
|
||||
}
|
||||
},
|
||||
"@types/eslint": {
|
||||
"version": "8.4.5",
|
||||
|
@ -5393,12 +5636,13 @@
|
|||
}
|
||||
},
|
||||
"call-bind": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/call-bind/-/call-bind-1.0.2.tgz",
|
||||
"integrity": "sha1-sdTonmiBGcPJqQOtMKuy9qkZvjw=",
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/call-bind/-/call-bind-1.0.5.tgz",
|
||||
"integrity": "sha1-b6K3hFzg6km/TYue9kcnosLi5RM=",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"get-intrinsic": "^1.0.2"
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.1",
|
||||
"set-function-length": "^1.1.1"
|
||||
}
|
||||
},
|
||||
"camelcase": {
|
||||
|
@ -5641,6 +5885,16 @@
|
|||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/defer-to-connect/-/defer-to-connect-2.0.1.tgz",
|
||||
"integrity": "sha1-gBa9tBQ+RjK3ejRJxiNid95SBYc="
|
||||
},
|
||||
"define-data-property": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/define-data-property/-/define-data-property-1.1.1.tgz",
|
||||
"integrity": "sha1-w1980KsJiDSA0SrFyyE3FVh4ALM=",
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.2.1",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"define-lazy-prop": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz",
|
||||
|
@ -5727,6 +5981,11 @@
|
|||
"integrity": "sha1-Bjd+Pl9NN5/qesWS1a2JJ+DE1HU=",
|
||||
"dev": true
|
||||
},
|
||||
"err-code": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/err-code/-/err-code-1.1.2.tgz",
|
||||
"integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA="
|
||||
},
|
||||
"es-module-lexer": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/es-module-lexer/-/es-module-lexer-1.3.0.tgz",
|
||||
|
@ -5806,6 +6065,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo="
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
|
@ -5860,6 +6124,52 @@
|
|||
"reusify": "^1.0.4"
|
||||
}
|
||||
},
|
||||
"file-js": {
|
||||
"version": "0.3.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/file-js/-/file-js-0.3.0.tgz",
|
||||
"integrity": "sha1-+rRr94I0bJKUSZ8fDSrQfYOPJdE=",
|
||||
"requires": {
|
||||
"bluebird": "^3.4.7",
|
||||
"minimatch": "^3.0.3",
|
||||
"proper-lockfile": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"filehound": {
|
||||
"version": "1.17.6",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/filehound/-/filehound-1.17.6.tgz",
|
||||
"integrity": "sha1-1dh71pQxbqZzvQZCt3a1CNP5ih0=",
|
||||
"requires": {
|
||||
"bluebird": "^3.7.2",
|
||||
"file-js": "0.3.0",
|
||||
"lodash": "^4.17.21",
|
||||
"minimatch": "^5.0.0",
|
||||
"moment": "^2.29.1",
|
||||
"unit-compare": "^1.0.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"bluebird": {
|
||||
"version": "3.7.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/bluebird/-/bluebird-3.7.2.tgz",
|
||||
"integrity": "sha1-nyKcFb4nJFT/qXOs4NvueaGww28="
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/brace-expansion/-/brace-expansion-2.0.1.tgz",
|
||||
"integrity": "sha1-HtxFng8MVISG7Pn8mfIiE2S5oK4=",
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "5.1.6",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/minimatch/-/minimatch-5.1.6.tgz",
|
||||
"integrity": "sha1-HPy4z1Ui6mmVLNKvla4JR38SKpY=",
|
||||
"requires": {
|
||||
"brace-expansion": "^2.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"fill-range": {
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/fill-range/-/fill-range-7.0.1.tgz",
|
||||
|
@ -5935,9 +6245,9 @@
|
|||
}
|
||||
},
|
||||
"function-bind": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/function-bind/-/function-bind-1.1.1.tgz",
|
||||
"integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0="
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/function-bind/-/function-bind-1.1.2.tgz",
|
||||
"integrity": "sha1-LALYZNl/PqbIgwxGTL0Rq26rehw="
|
||||
},
|
||||
"get-caller-file": {
|
||||
"version": "2.0.5",
|
||||
|
@ -5950,13 +6260,14 @@
|
|||
"integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE="
|
||||
},
|
||||
"get-intrinsic": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
|
||||
"integrity": "sha1-BjyEMprZPoOJPH9PJD72P/o1E4U=",
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/get-intrinsic/-/get-intrinsic-1.2.2.tgz",
|
||||
"integrity": "sha1-KBt2IpcRI+HvSzyQ/XU5MG2pPzs=",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.1",
|
||||
"has": "^1.0.3",
|
||||
"has-symbols": "^1.0.3"
|
||||
"function-bind": "^1.1.2",
|
||||
"has-proto": "^1.0.1",
|
||||
"has-symbols": "^1.0.3",
|
||||
"hasown": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"get-stream": {
|
||||
|
@ -6008,6 +6319,14 @@
|
|||
"slash": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"gopd": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/gopd/-/gopd-1.0.1.tgz",
|
||||
"integrity": "sha1-Kf923mnax0ibfAkYpXiOVkd8Myw=",
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.1.3"
|
||||
}
|
||||
},
|
||||
"got": {
|
||||
"version": "11.8.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/got/-/got-11.8.5.tgz",
|
||||
|
@ -6049,6 +6368,19 @@
|
|||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-flag/-/has-flag-4.0.0.tgz",
|
||||
"integrity": "sha1-lEdx/ZyByBJlxNaUGGDaBrtZR5s="
|
||||
},
|
||||
"has-property-descriptors": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz",
|
||||
"integrity": "sha1-UrowtsXsh/2J+ldLwcORJcb2U0A=",
|
||||
"requires": {
|
||||
"get-intrinsic": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"has-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-proto/-/has-proto-1.0.1.tgz",
|
||||
"integrity": "sha1-GIXBMFU4lYr/Rp/vN5N8InlUCOA="
|
||||
},
|
||||
"has-symbols": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-symbols/-/has-symbols-1.0.3.tgz",
|
||||
|
@ -6071,6 +6403,14 @@
|
|||
"minimalistic-assert": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"hasown": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/hasown/-/hasown-2.0.0.tgz",
|
||||
"integrity": "sha1-9MUT1FSle3x+FlB3jeImsRcAVGw=",
|
||||
"requires": {
|
||||
"function-bind": "^1.1.2"
|
||||
}
|
||||
},
|
||||
"he": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/he/-/he-1.2.0.tgz",
|
||||
|
@ -6512,6 +6852,11 @@
|
|||
"p-locate": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"lodash": {
|
||||
"version": "4.17.21",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/lodash/-/lodash-4.17.21.tgz",
|
||||
"integrity": "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw="
|
||||
},
|
||||
"log-symbols": {
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/log-symbols/-/log-symbols-4.1.0.tgz",
|
||||
|
@ -6678,6 +7023,11 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"moment": {
|
||||
"version": "2.30.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/moment/-/moment-2.30.1.tgz",
|
||||
"integrity": "sha1-+MkcB7enhuMMWZJt9TC06slpdK4="
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.1.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ms/-/ms-2.1.3.tgz",
|
||||
|
@ -6907,6 +7257,17 @@
|
|||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
|
||||
"integrity": "sha1-eCDZsWEgzFXKmud5JoCufbptf+I="
|
||||
},
|
||||
"proper-lockfile": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/proper-lockfile/-/proper-lockfile-1.2.0.tgz",
|
||||
"integrity": "sha1-zv9d2J0+XxD7deHo52vHWAGlnDQ=",
|
||||
"requires": {
|
||||
"err-code": "^1.0.0",
|
||||
"extend": "^3.0.0",
|
||||
"graceful-fs": "^4.1.2",
|
||||
"retry": "^0.10.0"
|
||||
}
|
||||
},
|
||||
"proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
|
@ -7134,6 +7495,11 @@
|
|||
"lowercase-keys": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"retry": {
|
||||
"version": "0.10.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/retry/-/retry-0.10.1.tgz",
|
||||
"integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q="
|
||||
},
|
||||
"reusify": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/reusify/-/reusify-1.0.4.tgz",
|
||||
|
@ -7157,6 +7523,24 @@
|
|||
"queue-microtask": "^1.2.2"
|
||||
}
|
||||
},
|
||||
"safe-array-concat": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/safe-array-concat/-/safe-array-concat-1.1.0.tgz",
|
||||
"integrity": "sha1-jQyunLgG1tHAbgirE9hHKT6+BpI=",
|
||||
"requires": {
|
||||
"call-bind": "^1.0.5",
|
||||
"get-intrinsic": "^1.2.2",
|
||||
"has-symbols": "^1.0.3",
|
||||
"isarray": "^2.0.5"
|
||||
},
|
||||
"dependencies": {
|
||||
"isarray": {
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/isarray/-/isarray-2.0.5.tgz",
|
||||
"integrity": "sha1-ivHkwSISRMxiRZ+vOJQNTmRKVyM="
|
||||
}
|
||||
}
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/safe-buffer/-/safe-buffer-5.2.1.tgz",
|
||||
|
@ -7195,6 +7579,18 @@
|
|||
"randombytes": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"set-function-length": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/set-function-length/-/set-function-length-1.2.0.tgz",
|
||||
"integrity": "sha1-L4HcbBbHBZvaWrfILBHwOlFe2OE=",
|
||||
"requires": {
|
||||
"define-data-property": "^1.1.1",
|
||||
"function-bind": "^1.1.2",
|
||||
"get-intrinsic": "^1.2.2",
|
||||
"gopd": "^1.0.1",
|
||||
"has-property-descriptors": "^1.0.1"
|
||||
}
|
||||
},
|
||||
"setimmediate": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/setimmediate/-/setimmediate-1.0.5.tgz",
|
||||
|
@ -7515,6 +7911,14 @@
|
|||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/typescript/-/typescript-4.4.4.tgz",
|
||||
"integrity": "sha1-LNAaGh8WBwTTEB/VpY/w+fy4Aww="
|
||||
},
|
||||
"unit-compare": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/unit-compare/-/unit-compare-1.0.1.tgz",
|
||||
"integrity": "sha1-DHRZ8OW/U2N+qHPKPO4Y3i7so4Y=",
|
||||
"requires": {
|
||||
"moment": "^2.14.1"
|
||||
}
|
||||
},
|
||||
"unzipper": {
|
||||
"version": "0.10.11",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/unzipper/-/unzipper-0.10.11.tgz",
|
||||
|
@ -7743,6 +8147,14 @@
|
|||
"wildcard": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"webpack-permissions-plugin": {
|
||||
"version": "1.0.9",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/webpack-permissions-plugin/-/webpack-permissions-plugin-1.0.9.tgz",
|
||||
"integrity": "sha1-gK5aCe0ZkdvbL5/kYYuNVxlhbh4=",
|
||||
"requires": {
|
||||
"filehound": "^1.17.6"
|
||||
}
|
||||
},
|
||||
"webpack-sources": {
|
||||
"version": "3.2.3",
|
||||
"resolved": "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/webpack-sources/-/webpack-sources-3.2.3.tgz",
|
||||
|
|
|
@ -68,7 +68,11 @@
|
|||
"dotnetAcquisitionExtension.existingDotnetPath": {
|
||||
"type": "array",
|
||||
"description": "File Path to an existing installation of .NET. Used for both the .NET SDK and .NET Runtime.",
|
||||
"examples": ["C:\\Program Files\\dotnet\\dotnet.exe", "/usr/local/share/dotnet/dotnet", "/usr/lib/dotnet/dotnet"]
|
||||
"examples": [
|
||||
"C:\\Program Files\\dotnet\\dotnet.exe",
|
||||
"/usr/local/share/dotnet/dotnet",
|
||||
"/usr/lib/dotnet/dotnet"
|
||||
]
|
||||
},
|
||||
"dotnetAcquisitionExtension.proxyUrl": {
|
||||
"type": "string",
|
||||
|
@ -88,6 +92,7 @@
|
|||
"webpack": "webpack --mode development"
|
||||
},
|
||||
"dependencies": {
|
||||
"@types/chai-as-promised": "^7.1.8",
|
||||
"axios": "^1.3.4",
|
||||
"axios-cache-interceptor": "^1.0.1",
|
||||
"axios-retry": "^3.4.0",
|
||||
|
@ -103,6 +108,7 @@
|
|||
"open": "^8.4.0",
|
||||
"public-ip": "5.0.0",
|
||||
"rimraf": "3.0.2",
|
||||
"safe-array-concat": "^1.1.0",
|
||||
"safe-regex-test": "^1.0.0",
|
||||
"shelljs": "^0.8.5",
|
||||
"ts-loader": "^9.2.6",
|
||||
|
@ -110,6 +116,7 @@
|
|||
"typescript": "4.4.4",
|
||||
"vscode-dotnet-runtime-library": "file:../vscode-dotnet-runtime-library",
|
||||
"vscode-test": "^1.6.1",
|
||||
"webpack-permissions-plugin": "^1.0.9",
|
||||
"yarn": "^1.22.19"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
|
||||
const path = require('path');
|
||||
const CopyPlugin = require('copy-webpack-plugin');
|
||||
const { exec } = require('node:child_process');
|
||||
const PermissionsOutputPlugin = require('webpack-permissions-plugin');
|
||||
|
||||
/**@type {import('webpack').Configuration}*/
|
||||
const config = {
|
||||
|
@ -50,6 +52,20 @@ const config = {
|
|||
{ from: path.resolve(__dirname, '../images'), to: path.resolve(__dirname, 'images') },
|
||||
{ from: path.resolve(__dirname, '../LICENSE.txt'), to: path.resolve(__dirname, 'LICENSE.txt') }
|
||||
]}),
|
||||
new PermissionsOutputPlugin({
|
||||
buildFolders: [
|
||||
],
|
||||
buildFiles: [
|
||||
{
|
||||
path: path.resolve(__dirname, 'dist', 'distro-data', 'distro-support.json'),
|
||||
fileMode: '544'
|
||||
},
|
||||
{
|
||||
path: path.resolve(__dirname, 'dist', 'install scripts', 'interprocess-communicator.sh'),
|
||||
fileMode: '500'
|
||||
}
|
||||
]
|
||||
})
|
||||
]
|
||||
};
|
||||
module.exports = config;
|
|
@ -152,7 +152,14 @@
|
|||
"@types/node" "*"
|
||||
"@types/responselike" "*"
|
||||
|
||||
"@types/chai@^4.3.5":
|
||||
"@types/chai-as-promised@^7.1.8":
|
||||
"integrity" "sha1-8rPYLVPFlia11rvAh2Z8y0tnf+k="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/chai-as-promised/-/chai-as-promised-7.1.8.tgz"
|
||||
"version" "7.1.8"
|
||||
dependencies:
|
||||
"@types/chai" "*"
|
||||
|
||||
"@types/chai@*", "@types/chai@^4.3.5":
|
||||
"integrity" "sha1-rmm8uxvrtoxKwLEenY7QRSazVis="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/@types/chai/-/chai-4.3.5.tgz"
|
||||
"version" "4.3.5"
|
||||
|
@ -546,11 +553,16 @@
|
|||
"buffers" "~0.1.1"
|
||||
"chainsaw" "~0.1.0"
|
||||
|
||||
"bluebird@~3.4.1":
|
||||
"bluebird@^3.4.7", "bluebird@~3.4.1":
|
||||
"integrity" "sha1-9y12C+Cbf3bQjtj66Ysomo0F+rM="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/bluebird/-/bluebird-3.4.7.tgz"
|
||||
"version" "3.4.7"
|
||||
|
||||
"bluebird@^3.7.2":
|
||||
"integrity" "sha1-nyKcFb4nJFT/qXOs4NvueaGww28="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/bluebird/-/bluebird-3.7.2.tgz"
|
||||
"version" "3.7.2"
|
||||
|
||||
"brace-expansion@^1.1.7":
|
||||
"integrity" "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/brace-expansion/-/brace-expansion-1.1.11.tgz"
|
||||
|
@ -559,6 +571,13 @@
|
|||
"balanced-match" "^1.0.0"
|
||||
"concat-map" "0.0.1"
|
||||
|
||||
"brace-expansion@^2.0.1":
|
||||
"integrity" "sha1-HtxFng8MVISG7Pn8mfIiE2S5oK4="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/brace-expansion/-/brace-expansion-2.0.1.tgz"
|
||||
"version" "2.0.1"
|
||||
dependencies:
|
||||
"balanced-match" "^1.0.0"
|
||||
|
||||
"braces@^3.0.2", "braces@~3.0.2":
|
||||
"integrity" "sha1-NFThpGLujVmeI23zNs2epPiv4Qc="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/braces/-/braces-3.0.2.tgz"
|
||||
|
@ -655,13 +674,14 @@
|
|||
"normalize-url" "^6.0.1"
|
||||
"responselike" "^2.0.0"
|
||||
|
||||
"call-bind@^1.0.2":
|
||||
"integrity" "sha1-sdTonmiBGcPJqQOtMKuy9qkZvjw="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/call-bind/-/call-bind-1.0.2.tgz"
|
||||
"version" "1.0.2"
|
||||
"call-bind@^1.0.2", "call-bind@^1.0.5":
|
||||
"integrity" "sha1-b6K3hFzg6km/TYue9kcnosLi5RM="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/call-bind/-/call-bind-1.0.5.tgz"
|
||||
"version" "1.0.5"
|
||||
dependencies:
|
||||
"function-bind" "^1.1.1"
|
||||
"get-intrinsic" "^1.0.2"
|
||||
"function-bind" "^1.1.2"
|
||||
"get-intrinsic" "^1.2.1"
|
||||
"set-function-length" "^1.1.1"
|
||||
|
||||
"camelcase@^6.0.0":
|
||||
"integrity" "sha1-VoW5XrIJrJwMF3Rnd4ychN9Yupo="
|
||||
|
@ -906,6 +926,15 @@
|
|||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/defer-to-connect/-/defer-to-connect-2.0.1.tgz"
|
||||
"version" "2.0.1"
|
||||
|
||||
"define-data-property@^1.1.1":
|
||||
"integrity" "sha1-w1980KsJiDSA0SrFyyE3FVh4ALM="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/define-data-property/-/define-data-property-1.1.1.tgz"
|
||||
"version" "1.1.1"
|
||||
dependencies:
|
||||
"get-intrinsic" "^1.2.1"
|
||||
"gopd" "^1.0.1"
|
||||
"has-property-descriptors" "^1.0.0"
|
||||
|
||||
"define-lazy-prop@^2.0.0":
|
||||
"integrity" "sha1-P3rkIRKbyqrJvHSQXJigAJ7J7n8="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz"
|
||||
|
@ -994,6 +1023,11 @@
|
|||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/envinfo/-/envinfo-7.8.1.tgz"
|
||||
"version" "7.8.1"
|
||||
|
||||
"err-code@^1.0.0":
|
||||
"integrity" "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/err-code/-/err-code-1.1.2.tgz"
|
||||
"version" "1.1.2"
|
||||
|
||||
"es-module-lexer@^1.2.1":
|
||||
"integrity" "sha1-a+nJ4LRUOmDNFm/2+LTp2uCwwW8="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/es-module-lexer/-/es-module-lexer-1.3.0.tgz"
|
||||
|
@ -1064,6 +1098,11 @@
|
|||
"signal-exit" "^3.0.3"
|
||||
"strip-final-newline" "^2.0.0"
|
||||
|
||||
"extend@^3.0.0":
|
||||
"integrity" "sha1-+LETa0Bx+9jrFAr/hYsQGewpFfo="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/extend/-/extend-3.0.2.tgz"
|
||||
"version" "3.0.2"
|
||||
|
||||
"fast-deep-equal@^3.1.1":
|
||||
"integrity" "sha1-On1WtVnWy8PrUSMlJE5hmmXGxSU="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz"
|
||||
|
@ -1102,6 +1141,27 @@
|
|||
dependencies:
|
||||
"reusify" "^1.0.4"
|
||||
|
||||
"file-js@0.3.0":
|
||||
"integrity" "sha1-+rRr94I0bJKUSZ8fDSrQfYOPJdE="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/file-js/-/file-js-0.3.0.tgz"
|
||||
"version" "0.3.0"
|
||||
dependencies:
|
||||
"bluebird" "^3.4.7"
|
||||
"minimatch" "^3.0.3"
|
||||
"proper-lockfile" "^1.2.0"
|
||||
|
||||
"filehound@^1.17.6":
|
||||
"integrity" "sha1-1dh71pQxbqZzvQZCt3a1CNP5ih0="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/filehound/-/filehound-1.17.6.tgz"
|
||||
"version" "1.17.6"
|
||||
dependencies:
|
||||
"bluebird" "^3.7.2"
|
||||
"file-js" "0.3.0"
|
||||
"lodash" "^4.17.21"
|
||||
"minimatch" "^5.0.0"
|
||||
"moment" "^2.29.1"
|
||||
"unit-compare" "^1.0.1"
|
||||
|
||||
"fill-range@^7.0.1":
|
||||
"integrity" "sha1-GRmmp8df44ssfHflGYU12prN2kA="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/fill-range/-/fill-range-7.0.1.tgz"
|
||||
|
@ -1164,10 +1224,10 @@
|
|||
"mkdirp" ">=0.5 0"
|
||||
"rimraf" "2"
|
||||
|
||||
"function-bind@^1.1.1":
|
||||
"integrity" "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/function-bind/-/function-bind-1.1.1.tgz"
|
||||
"version" "1.1.1"
|
||||
"function-bind@^1.1.1", "function-bind@^1.1.2":
|
||||
"integrity" "sha1-LALYZNl/PqbIgwxGTL0Rq26rehw="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/function-bind/-/function-bind-1.1.2.tgz"
|
||||
"version" "1.1.2"
|
||||
|
||||
"get-caller-file@^2.0.5":
|
||||
"integrity" "sha1-T5RBKoLbMvNuOwuXQfipf+sDH34="
|
||||
|
@ -1179,14 +1239,15 @@
|
|||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/get-func-name/-/get-func-name-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
|
||||
"get-intrinsic@^1.0.2", "get-intrinsic@^1.1.3":
|
||||
"integrity" "sha1-BjyEMprZPoOJPH9PJD72P/o1E4U="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/get-intrinsic/-/get-intrinsic-1.1.3.tgz"
|
||||
"version" "1.1.3"
|
||||
"get-intrinsic@^1.1.3", "get-intrinsic@^1.2.1", "get-intrinsic@^1.2.2":
|
||||
"integrity" "sha1-KBt2IpcRI+HvSzyQ/XU5MG2pPzs="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/get-intrinsic/-/get-intrinsic-1.2.2.tgz"
|
||||
"version" "1.2.2"
|
||||
dependencies:
|
||||
"function-bind" "^1.1.1"
|
||||
"has" "^1.0.3"
|
||||
"function-bind" "^1.1.2"
|
||||
"has-proto" "^1.0.1"
|
||||
"has-symbols" "^1.0.3"
|
||||
"hasown" "^2.0.0"
|
||||
|
||||
"get-stream@^4.1.0":
|
||||
"integrity" "sha1-wbJVV189wh1Zv8ec09K0axw6VLU="
|
||||
|
@ -1274,6 +1335,13 @@
|
|||
"merge2" "^1.4.1"
|
||||
"slash" "^3.0.0"
|
||||
|
||||
"gopd@^1.0.1":
|
||||
"integrity" "sha1-Kf923mnax0ibfAkYpXiOVkd8Myw="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/gopd/-/gopd-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
dependencies:
|
||||
"get-intrinsic" "^1.1.3"
|
||||
|
||||
"got@^11.8.0", "got@11.8.5":
|
||||
"integrity" "sha1-znfQRRNt5W6PAkvruC6jSbxzAEY="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/got/-/got-11.8.5.tgz"
|
||||
|
@ -1345,6 +1413,18 @@
|
|||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-flag/-/has-flag-4.0.0.tgz"
|
||||
"version" "4.0.0"
|
||||
|
||||
"has-property-descriptors@^1.0.0", "has-property-descriptors@^1.0.1":
|
||||
"integrity" "sha1-UrowtsXsh/2J+ldLwcORJcb2U0A="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
dependencies:
|
||||
"get-intrinsic" "^1.2.2"
|
||||
|
||||
"has-proto@^1.0.1":
|
||||
"integrity" "sha1-GIXBMFU4lYr/Rp/vN5N8InlUCOA="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-proto/-/has-proto-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
|
||||
"has-symbols@^1.0.2", "has-symbols@^1.0.3":
|
||||
"integrity" "sha1-u3ssQ0klHc6HsSX3vfh0qnyLOfg="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/has-symbols/-/has-symbols-1.0.3.tgz"
|
||||
|
@ -1372,6 +1452,13 @@
|
|||
"inherits" "^2.0.3"
|
||||
"minimalistic-assert" "^1.0.1"
|
||||
|
||||
"hasown@^2.0.0":
|
||||
"integrity" "sha1-9MUT1FSle3x+FlB3jeImsRcAVGw="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/hasown/-/hasown-2.0.0.tgz"
|
||||
"version" "2.0.0"
|
||||
dependencies:
|
||||
"function-bind" "^1.1.2"
|
||||
|
||||
"he@1.2.0":
|
||||
"integrity" "sha1-hK5l+n6vsWX922FWauFLrwVmTw8="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/he/-/he-1.2.0.tgz"
|
||||
|
@ -1583,6 +1670,11 @@
|
|||
dependencies:
|
||||
"is-docker" "^2.0.0"
|
||||
|
||||
"isarray@^2.0.5":
|
||||
"integrity" "sha1-ivHkwSISRMxiRZ+vOJQNTmRKVyM="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/isarray/-/isarray-2.0.5.tgz"
|
||||
"version" "2.0.5"
|
||||
|
||||
"isarray@~1.0.0":
|
||||
"integrity" "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/isarray/-/isarray-1.0.0.tgz"
|
||||
|
@ -1690,6 +1782,11 @@
|
|||
dependencies:
|
||||
"p-locate" "^5.0.0"
|
||||
|
||||
"lodash@^4.17.21":
|
||||
"integrity" "sha1-Z5WRxWTDv/quhFTPCz3zcMPWkRw="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/lodash/-/lodash-4.17.21.tgz"
|
||||
"version" "4.17.21"
|
||||
|
||||
"log-symbols@4.1.0":
|
||||
"integrity" "sha1-P727lbRoOsn8eFER55LlWNSr1QM="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/log-symbols/-/log-symbols-4.1.0.tgz"
|
||||
|
@ -1785,13 +1882,20 @@
|
|||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
|
||||
"minimatch@^3.0.4", "minimatch@^3.1.1":
|
||||
"minimatch@^3.0.3", "minimatch@^3.0.4", "minimatch@^3.1.1":
|
||||
"integrity" "sha1-Gc0ZS/0+Qo8EmnCBfAONiatL41s="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/minimatch/-/minimatch-3.1.2.tgz"
|
||||
"version" "3.1.2"
|
||||
dependencies:
|
||||
"brace-expansion" "^1.1.7"
|
||||
|
||||
"minimatch@^5.0.0":
|
||||
"integrity" "sha1-HPy4z1Ui6mmVLNKvla4JR38SKpY="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/minimatch/-/minimatch-5.1.6.tgz"
|
||||
"version" "5.1.6"
|
||||
dependencies:
|
||||
"brace-expansion" "^2.0.1"
|
||||
|
||||
"minimatch@4.2.1":
|
||||
"integrity" "sha1-QNnVEaRr3E5WPCLDCAzenA2CmbQ="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/minimatch/-/minimatch-4.2.1.tgz"
|
||||
|
@ -1841,6 +1945,11 @@
|
|||
"yargs-parser" "20.2.4"
|
||||
"yargs-unparser" "2.0.0"
|
||||
|
||||
"moment@^2.14.1", "moment@^2.29.1":
|
||||
"integrity" "sha1-+MkcB7enhuMMWZJt9TC06slpdK4="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/moment/-/moment-2.30.1.tgz"
|
||||
"version" "2.30.1"
|
||||
|
||||
"ms@2.1.2":
|
||||
"integrity" "sha1-0J0fNXtEP0kzgqjrPM0YOHKuYAk="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/ms/-/ms-2.1.2.tgz"
|
||||
|
@ -2054,6 +2163,16 @@
|
|||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/process-nextick-args/-/process-nextick-args-2.0.1.tgz"
|
||||
"version" "2.0.1"
|
||||
|
||||
"proper-lockfile@^1.2.0":
|
||||
"integrity" "sha1-zv9d2J0+XxD7deHo52vHWAGlnDQ="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/proper-lockfile/-/proper-lockfile-1.2.0.tgz"
|
||||
"version" "1.2.0"
|
||||
dependencies:
|
||||
"err-code" "^1.0.0"
|
||||
"extend" "^3.0.0"
|
||||
"graceful-fs" "^4.1.2"
|
||||
"retry" "^0.10.0"
|
||||
|
||||
"proxy-from-env@^1.1.0":
|
||||
"integrity" "sha1-4QLxbKNVQkhldV0sno6k8k1Yw+I="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/proxy-from-env/-/proxy-from-env-1.1.0.tgz"
|
||||
|
@ -2198,6 +2317,11 @@
|
|||
dependencies:
|
||||
"lowercase-keys" "^3.0.0"
|
||||
|
||||
"retry@^0.10.0":
|
||||
"integrity" "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/retry/-/retry-0.10.1.tgz"
|
||||
"version" "0.10.1"
|
||||
|
||||
"reusify@^1.0.4":
|
||||
"integrity" "sha1-kNo4Kx4SbvwCFG6QhFqI2xKSXXY="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/reusify/-/reusify-1.0.4.tgz"
|
||||
|
@ -2224,6 +2348,16 @@
|
|||
dependencies:
|
||||
"queue-microtask" "^1.2.2"
|
||||
|
||||
"safe-array-concat@^1.1.0":
|
||||
"integrity" "sha1-jQyunLgG1tHAbgirE9hHKT6+BpI="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/safe-array-concat/-/safe-array-concat-1.1.0.tgz"
|
||||
"version" "1.1.0"
|
||||
dependencies:
|
||||
"call-bind" "^1.0.5"
|
||||
"get-intrinsic" "^1.2.2"
|
||||
"has-symbols" "^1.0.3"
|
||||
"isarray" "^2.0.5"
|
||||
|
||||
"safe-buffer@^5.1.0":
|
||||
"integrity" "sha1-Hq+fqb2x/dTsdfWPnNtOa3gn7sY="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/safe-buffer/-/safe-buffer-5.2.1.tgz"
|
||||
|
@ -2283,6 +2417,17 @@
|
|||
dependencies:
|
||||
"randombytes" "^2.1.0"
|
||||
|
||||
"set-function-length@^1.1.1":
|
||||
"integrity" "sha1-L4HcbBbHBZvaWrfILBHwOlFe2OE="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/set-function-length/-/set-function-length-1.2.0.tgz"
|
||||
"version" "1.2.0"
|
||||
dependencies:
|
||||
"define-data-property" "^1.1.1"
|
||||
"function-bind" "^1.1.2"
|
||||
"get-intrinsic" "^1.2.2"
|
||||
"gopd" "^1.0.1"
|
||||
"has-property-descriptors" "^1.0.1"
|
||||
|
||||
"setimmediate@~1.0.4":
|
||||
"integrity" "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/setimmediate/-/setimmediate-1.0.5.tgz"
|
||||
|
@ -2497,6 +2642,13 @@
|
|||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/typescript/-/typescript-4.4.4.tgz"
|
||||
"version" "4.4.4"
|
||||
|
||||
"unit-compare@^1.0.1":
|
||||
"integrity" "sha1-DHRZ8OW/U2N+qHPKPO4Y3i7so4Y="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/unit-compare/-/unit-compare-1.0.1.tgz"
|
||||
"version" "1.0.1"
|
||||
dependencies:
|
||||
"moment" "^2.14.1"
|
||||
|
||||
"unzipper@^0.10.11":
|
||||
"integrity" "sha1-C0mRRGRyy9uS7nQDkJ8mwkGceC4="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/unzipper/-/unzipper-0.10.11.tgz"
|
||||
|
@ -2625,6 +2777,13 @@
|
|||
"clone-deep" "^4.0.1"
|
||||
"wildcard" "^2.0.0"
|
||||
|
||||
"webpack-permissions-plugin@^1.0.9":
|
||||
"integrity" "sha1-gK5aCe0ZkdvbL5/kYYuNVxlhbh4="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/webpack-permissions-plugin/-/webpack-permissions-plugin-1.0.9.tgz"
|
||||
"version" "1.0.9"
|
||||
dependencies:
|
||||
"filehound" "^1.17.6"
|
||||
|
||||
"webpack-sources@^3.2.3":
|
||||
"integrity" "sha1-LU2quEUf1LJAzCcFX/agwszqDN4="
|
||||
"resolved" "https://pkgs.dev.azure.com/dnceng/public/_packaging/dotnet-public-npm/npm/registry/webpack-sources/-/webpack-sources-3.2.3.tgz"
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
{
|
||||
"runUnderSudo": false,
|
||||
"commandRoot": "apt-cache",
|
||||
"commandParts": ["search", "{packageName}"]
|
||||
"commandParts": ["search", "--names-only", "^{packageName}$"]
|
||||
}
|
||||
],
|
||||
"isInstalledCommand":
|
||||
|
@ -132,6 +132,30 @@
|
|||
[
|
||||
"aspnetcore-runtime-7.0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "8.0",
|
||||
"sdk": [
|
||||
"dotnet-sdk-8.0"
|
||||
],
|
||||
"runtime": [
|
||||
"dotnet-runtime-8.0"
|
||||
],
|
||||
"aspnetcore": [
|
||||
"aspnetcore-runtime-8.0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "9.0",
|
||||
"sdk": [
|
||||
"dotnet-sdk-9.0"
|
||||
],
|
||||
"runtime": [
|
||||
"dotnet-runtime-9.0"
|
||||
],
|
||||
"aspnetcore": [
|
||||
"aspnetcore-runtime-9.0"
|
||||
]
|
||||
}
|
||||
],
|
||||
"versions": [{
|
||||
|
@ -333,6 +357,30 @@
|
|||
"aspnetcore": [
|
||||
"aspnetcore-runtime-7.0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "8.0",
|
||||
"sdk": [
|
||||
"dotnet-sdk-8.0"
|
||||
],
|
||||
"runtime": [
|
||||
"dotnet-runtime-8.0"
|
||||
],
|
||||
"aspnetcore": [
|
||||
"aspnetcore-runtime-8.0"
|
||||
]
|
||||
},
|
||||
{
|
||||
"version": "9.0",
|
||||
"sdk": [
|
||||
"dotnet-sdk-9.0"
|
||||
],
|
||||
"runtime": [
|
||||
"dotnet-runtime-9.0"
|
||||
],
|
||||
"aspnetcore": [
|
||||
"aspnetcore-runtime-9.0"
|
||||
]
|
||||
}
|
||||
],
|
||||
"versions": [
|
||||
|
|
|
@ -0,0 +1,45 @@
|
|||
#!/usr/bin/env bash
|
||||
EXECFOLDER=$1 # First argument is the working folder as this is launched with cwd of /root
|
||||
OKSIGNALFILE="$EXECFOLDER/ok.txt"
|
||||
COMMANDTORUNFILE="$EXECFOLDER/command.txt"
|
||||
#OUTPUTFILE="/home/test_output_.txt"
|
||||
end=$((SECONDS+3600))
|
||||
|
||||
function finish {
|
||||
rm "$COMMANDTORUNFILE"
|
||||
rm "$OKSIGNALFILE"
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
while true
|
||||
do
|
||||
stop=false
|
||||
while [ $SECONDS -lt $end ];
|
||||
do
|
||||
if test -f "$COMMANDTORUNFILE"; then
|
||||
# echo "COMMAND FILE FOUND" >> "$OUTPUTFILE" # Leave this here as an example of debugging
|
||||
COMMAND="$(cat "$COMMANDTORUNFILE" | awk '{$1=$1;print}')"
|
||||
for validCmd in "${@:2}"
|
||||
do
|
||||
if [ "$COMMAND" == "$validCmd" ]; then
|
||||
# Eventually we should split the cmd file to be line by line instead of space separated,
|
||||
# but it works for now because the commands are running under sudo
|
||||
IFS=' ' read -ra COMMANDARGS <<< "$COMMAND"
|
||||
fi
|
||||
done
|
||||
if [ -z "$COMMANDARGS" ]; then
|
||||
rm "$COMMANDTORUNFILE"
|
||||
exit 111777 # Special exit code - arbitrarily picked for when the command is not expected
|
||||
fi
|
||||
sudo "${COMMANDARGS[@]}" 2> "$EXECFOLDER/stderr.txt" 1> "$EXECFOLDER/stdout.txt"
|
||||
STATUSCODE=$?
|
||||
echo $STATUSCODE > "$EXECFOLDER/status.txt"
|
||||
rm "$COMMANDTORUNFILE"
|
||||
touch "$EXECFOLDER/output.txt"
|
||||
fi
|
||||
if test -f "$OKSIGNALFILE"; then
|
||||
rm "$OKSIGNALFILE"
|
||||
fi
|
||||
sleep 5
|
||||
done
|
||||
done
|
|
@ -182,7 +182,7 @@ export class GenericDistroSDKProvider extends IDistroDotnetSDKProvider
|
|||
}
|
||||
else
|
||||
{
|
||||
const availableVersions = await this.myVersionPackages(installType);
|
||||
const availableVersions = await this.myVersionPackages(installType, this.isMidFeedInjection);
|
||||
const simplifiedVersion = this.JsonDotnetVersion(fullySpecifiedVersion);
|
||||
|
||||
for(const dotnetPackages of availableVersions)
|
||||
|
@ -200,7 +200,7 @@ export class GenericDistroSDKProvider extends IDistroDotnetSDKProvider
|
|||
public async getRecommendedDotnetVersion(installType : LinuxInstallType) : Promise<string>
|
||||
{
|
||||
let maxVersion = '0';
|
||||
const json = await this.myVersionPackages(installType);
|
||||
const json = await this.myVersionPackages(installType, this.isMidFeedInjection);
|
||||
for(const dotnetPackages of json)
|
||||
{
|
||||
if(Number(dotnetPackages.version) > Number(maxVersion))
|
||||
|
@ -218,7 +218,7 @@ export class GenericDistroSDKProvider extends IDistroDotnetSDKProvider
|
|||
return this.versionResolver.getMajorMinor(fullySpecifiedDotnetVersion);
|
||||
}
|
||||
|
||||
protected isPackageFoundInSearch(resultOfSearchCommand: any): boolean {
|
||||
return resultOfSearchCommand !== '';
|
||||
protected isPackageFoundInSearch(resultOfSearchCommand: any, searchCommandExitCode : string): boolean {
|
||||
return resultOfSearchCommand.trim() !== '' && searchCommandExitCode === '0';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,15 +4,13 @@
|
|||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
|
||||
import path = require('path');
|
||||
|
||||
import { DistroVersionPair, DotnetDistroSupportStatus } from './LinuxVersionResolver';
|
||||
import { DotnetAcquisitionDistroUnknownError, DotnetVersionResolutionError } from '../EventStream/EventStreamEvents';
|
||||
import { DotnetAcquisitionDistroUnknownError, DotnetVersionResolutionError, SuppressedAcquisitionError } from '../EventStream/EventStreamEvents';
|
||||
import { VersionResolver } from './VersionResolver';
|
||||
import { CommandExecutorCommand } from '../Utils/CommandExecutorCommand';
|
||||
import { DotnetCoreAcquisitionWorker } from './DotnetCoreAcquisitionWorker';
|
||||
import { CommandExecutor } from '../Utils/CommandExecutor';
|
||||
import { LinuxInstallType } from './LinuxInstallType';
|
||||
import { LinuxPackageCollection } from './LinuxPackageCollection';
|
||||
|
@ -62,14 +60,24 @@ export abstract class IDistroDotnetSDKProvider {
|
|||
protected runtimeKey = 'runtime';
|
||||
protected aspNetKey = 'aspnetcore';
|
||||
|
||||
protected isMidFeedInjection = false;
|
||||
protected cachedMyVersionPacakges : any = null;
|
||||
|
||||
constructor(distroVersion : DistroVersionPair, context : IAcquisitionWorkerContext, utilContext : IUtilityContext, executor : ICommandExecutor | null = null)
|
||||
{
|
||||
this.commandRunner = executor ?? new CommandExecutor(context, utilContext);
|
||||
this.context = context;
|
||||
this.distroVersion = distroVersion;
|
||||
this.versionResolver = new VersionResolver(context);
|
||||
// Hard-code to the upper path (lib/dist/acquisition) from __dirname to the lib folder, as webpack-copy doesn't seem to copy the distro-support.json
|
||||
const distroDataFile = path.join(__dirname, 'distro-data', `distro-support.json`);
|
||||
try
|
||||
{
|
||||
fs.chmodSync(distroDataFile, 0o544);
|
||||
}
|
||||
catch(error : any)
|
||||
{
|
||||
this.context.eventStream.post(new SuppressedAcquisitionError(error, `Failed to chmod +x on .NET folder ${distroDataFile} when marked for deletion.`));
|
||||
}
|
||||
|
||||
this.distroJson = JSON.parse(fs.readFileSync(distroDataFile, 'utf8'));
|
||||
if(!distroVersion || !this.distroJson || !((this.distroJson as any)[this.distroVersion.distro]))
|
||||
{
|
||||
|
@ -77,6 +85,9 @@ export abstract class IDistroDotnetSDKProvider {
|
|||
getInstallKeyFromContext(this.context.acquisitionContext));
|
||||
throw error.error;
|
||||
}
|
||||
|
||||
const validCommandSet = this.getAllValidCommands();
|
||||
this.commandRunner = executor ?? new CommandExecutor(context, utilContext, validCommandSet);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,6 +187,11 @@ export abstract class IDistroDotnetSDKProvider {
|
|||
|
||||
protected async myVersionPackages(installType : LinuxInstallType, haveTriedFeedInjectionAlready = false) : Promise<LinuxPackageCollection[]>
|
||||
{
|
||||
if(this.cachedMyVersionPacakges)
|
||||
{
|
||||
return this.cachedMyVersionPacakges;
|
||||
}
|
||||
|
||||
const availableVersions : LinuxPackageCollection[] = [];
|
||||
|
||||
const potentialDotnetPackageNames = this.distroJson[this.distroVersion.distro][this.distroPackagesKey];
|
||||
|
@ -191,8 +207,15 @@ export abstract class IDistroDotnetSDKProvider {
|
|||
{
|
||||
let command = this.myDistroCommands(this.searchCommandKey);
|
||||
command = CommandExecutor.replaceSubstringsInCommands(command, this.missingPackageNameKey, packageName);
|
||||
const packageIsAvailableResult = (await this.commandRunner.executeMultipleCommands(command))[0];
|
||||
const packageExists = this.isPackageFoundInSearch(packageIsAvailableResult);
|
||||
|
||||
const packageIsAvailableResult = (await this.commandRunner.executeMultipleCommands(command))[0].trim();
|
||||
const oldReturnStatusSetting = this.commandRunner.returnStatus;
|
||||
|
||||
this.commandRunner.returnStatus = true;
|
||||
const packageAvailableExitCode = (await this.commandRunner.executeMultipleCommands(command))[0].trim();
|
||||
this.commandRunner.returnStatus = oldReturnStatusSetting;
|
||||
|
||||
const packageExists = this.isPackageFoundInSearch(packageIsAvailableResult, packageAvailableExitCode);
|
||||
if(packageExists)
|
||||
{
|
||||
thisVersionPackage.packages.push(packageName);
|
||||
|
@ -212,13 +235,24 @@ export abstract class IDistroDotnetSDKProvider {
|
|||
const fakeVersionToCheckMicrosoftSupportStatus = '6.0.1xx';
|
||||
|
||||
await this.injectPMCFeed(fakeVersionToCheckMicrosoftSupportStatus, installType);
|
||||
return this.myVersionPackages(installType, true);
|
||||
this.cachedMyVersionPacakges = this.myVersionPackages(installType, true);
|
||||
}
|
||||
return availableVersions;
|
||||
else
|
||||
{
|
||||
this.cachedMyVersionPacakges = availableVersions;
|
||||
}
|
||||
|
||||
return this.cachedMyVersionPacakges;
|
||||
}
|
||||
|
||||
protected async injectPMCFeed(fullySpecifiedVersion : string, installType : LinuxInstallType)
|
||||
{
|
||||
if(this.isMidFeedInjection)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
this.isMidFeedInjection = true;
|
||||
const supportStatus = await this.getDotnetVersionSupportStatus(fullySpecifiedVersion, installType);
|
||||
if(supportStatus === DotnetDistroSupportStatus.Microsoft)
|
||||
{
|
||||
|
@ -226,6 +260,8 @@ export abstract class IDistroDotnetSDKProvider {
|
|||
const preInstallCommands = myVersionDetails[this.preinstallCommandKey] as CommandExecutorCommand[];
|
||||
await this.commandRunner.executeMultipleCommands(preInstallCommands);
|
||||
}
|
||||
|
||||
this.isMidFeedInjection = false;
|
||||
}
|
||||
|
||||
protected myVersionDetails() : any
|
||||
|
@ -269,9 +305,53 @@ export abstract class IDistroDotnetSDKProvider {
|
|||
return this.distroJson[this.distroVersion.distro][commandKey] as CommandExecutorCommand[];
|
||||
}
|
||||
|
||||
protected getAllValidCommands() : string[]
|
||||
{
|
||||
const validCommands : string[] = [];
|
||||
|
||||
const baseCommands = (Object.values(this.distroJson[this.distroVersion.distro])
|
||||
.filter((x : any) => x && Array.isArray(x) && ((x[0] as CommandExecutorCommand).commandParts))).flat();
|
||||
let preInstallCommands = this.myVersionDetails()[this.preinstallCommandKey] as CommandExecutorCommand[];
|
||||
if(!preInstallCommands)
|
||||
{
|
||||
preInstallCommands = [];
|
||||
}
|
||||
const sudoCommands = (baseCommands as CommandExecutorCommand[]).concat(preInstallCommands).filter(x => x.runUnderSudo);
|
||||
|
||||
for(const command of sudoCommands)
|
||||
{
|
||||
if(command.commandParts.slice(-1)[0] !== this.missingPackageNameKey)
|
||||
{
|
||||
validCommands.push(`"${CommandExecutor.prettifyCommandExecutorCommand(command, false)}"`);
|
||||
}
|
||||
else
|
||||
{
|
||||
for(const packageName of this.allPackages())
|
||||
{
|
||||
const newCommand = CommandExecutor.replaceSubstringsInCommands([command], this.missingPackageNameKey, packageName)[0];
|
||||
validCommands.push(`"${CommandExecutor.prettifyCommandExecutorCommand(newCommand, false)}"`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return [...new Set(validCommands)];
|
||||
}
|
||||
|
||||
protected allPackages() : string[]
|
||||
{
|
||||
let allPackages : string[] = [];
|
||||
const distroPackages = this.distroJson[this.distroVersion.distro][this.distroPackagesKey];
|
||||
for(const packageSet of distroPackages)
|
||||
{
|
||||
allPackages = allPackages.concat(packageSet[this.sdkKey]);
|
||||
allPackages = allPackages.concat(packageSet[this.runtimeKey])
|
||||
allPackages = allPackages.concat(packageSet[this.aspNetKey])
|
||||
}
|
||||
return allPackages;
|
||||
}
|
||||
|
||||
protected async myDotnetVersionPackageName(fullySpecifiedDotnetVersion : string, installType : LinuxInstallType) : Promise<string>
|
||||
{
|
||||
const myDotnetVersions = await this.myVersionPackages(installType);
|
||||
const myDotnetVersions = await this.myVersionPackages(installType, this.isMidFeedInjection);
|
||||
for(const dotnetPackage of myDotnetVersions)
|
||||
{
|
||||
if(dotnetPackage.version === this.JsonDotnetVersion(fullySpecifiedDotnetVersion))
|
||||
|
@ -280,10 +360,10 @@ export abstract class IDistroDotnetSDKProvider {
|
|||
return dotnetPackage.packages[0];
|
||||
}
|
||||
}
|
||||
const err = new Error(`Could not find a .NET package for version ${fullySpecifiedDotnetVersion}. Found only: ${JSON.stringify(await this.myVersionPackages(installType))}`);
|
||||
const err = new Error(`Could not find a .NET package for version ${fullySpecifiedDotnetVersion}. Found only: ${JSON.stringify(myDotnetVersions)}`);
|
||||
this.context.eventStream.post(new DotnetVersionResolutionError(err, getInstallKeyFromContext(this.context.acquisitionContext)));
|
||||
throw err;
|
||||
}
|
||||
|
||||
protected abstract isPackageFoundInSearch(resultOfSearchCommand : any) : boolean;
|
||||
protected abstract isPackageFoundInSearch(resultOfSearchCommand : any, searchCommandExitCode : string) : boolean;
|
||||
}
|
|
@ -43,7 +43,7 @@ export class InstallScriptAcquisitionWorker implements IInstallScriptAcquisition
|
|||
throw new Error('Unable to get script path.');
|
||||
}
|
||||
|
||||
await this.fileUtilities.writeFileOntoDisk(script, this.scriptFilePath, this.context.eventStream);
|
||||
await this.fileUtilities.writeFileOntoDisk(script, this.scriptFilePath, false, this.context.eventStream);
|
||||
this.context.eventStream.post(new DotnetInstallScriptAcquisitionCompleted());
|
||||
return this.scriptFilePath;
|
||||
}
|
||||
|
|
|
@ -187,6 +187,18 @@ export class DotnetPreinstallDetectionError extends DotnetAcquisitionError {
|
|||
public readonly eventName = 'DotnetPreinstallDetectionError';
|
||||
}
|
||||
|
||||
export class TimeoutSudoProcessSpawnerError extends DotnetAcquisitionError {
|
||||
public readonly eventName = 'TimeoutSudoProcessSpawnerError';
|
||||
}
|
||||
|
||||
export class TimeoutSudoCommandExecutionError extends DotnetAcquisitionError {
|
||||
public readonly eventName = 'TimeoutSudoCommandExecutionError';
|
||||
}
|
||||
|
||||
export class CommandExecutionNonZeroExitFailure extends DotnetAcquisitionError {
|
||||
public readonly eventName = 'CommandExecutionNonZeroExitFailure';
|
||||
}
|
||||
|
||||
export class DotnetNotInstallRelatedCommandFailed extends DotnetNonAcquisitionError {
|
||||
public readonly eventName = 'DotnetNotInstallRelatedCommandFailed';
|
||||
|
||||
|
@ -488,6 +500,18 @@ export class DotnetGlobalVersionResolutionCompletionEvent extends DotnetCustomMe
|
|||
public readonly eventName = 'DotnetGlobalVersionResolutionCompletionEvent';
|
||||
}
|
||||
|
||||
export class CommandProcessesExecutionFailureNonTerminal extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'CommandProcessesExecutionFailureNonTerminal';
|
||||
}
|
||||
|
||||
export class CommandProcessorExecutionBegin extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'CommandProcessorExecutionBegin';
|
||||
}
|
||||
|
||||
export class CommandProcessorExecutionEnd extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'CommandProcessorExecutionEnd';
|
||||
}
|
||||
|
||||
export class DotnetBeginGlobalInstallerExecution extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'DotnetBeginGlobalInstallerExecution';
|
||||
}
|
||||
|
@ -547,6 +571,26 @@ export class CommandExecutionEvent extends DotnetCustomMessageEvent {
|
|||
public readonly eventName = 'CommandExecutionEvent';
|
||||
}
|
||||
|
||||
export class SudoProcAliveCheckBegin extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'SudoProcAliveCheckBegin';
|
||||
}
|
||||
|
||||
export class SudoProcAliveCheckEnd extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'SudoProcAliveCheckEnd';
|
||||
}
|
||||
|
||||
export class SudoProcCommandExchangeBegin extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'SudoProcCommandExchangeBegin';
|
||||
}
|
||||
|
||||
export class SudoProcCommandExchangePing extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'SudoProcCommandExchangePing';
|
||||
}
|
||||
|
||||
export class SudoProcCommandExchangeEnd extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'SudoProcCommandExchangeEnd';
|
||||
}
|
||||
|
||||
export class CommandExecutionUserAskDialogueEvent extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'CommandExecutionUserAskDialogueEvent';
|
||||
}
|
||||
|
@ -563,6 +607,10 @@ export class CommandExecutionUserRejectedPasswordRequest extends DotnetInstallEx
|
|||
public readonly eventName = 'CommandExecutionUserRejectedPasswordRequest';
|
||||
}
|
||||
|
||||
export class CommandExecutionUnknownCommandExecutionAttempt extends DotnetInstallExpectedAbort {
|
||||
public readonly eventName = 'CommandExecutionUnknownCommandExecutionAttempt';
|
||||
}
|
||||
|
||||
export class DotnetVersionParseEvent extends DotnetCustomMessageEvent {
|
||||
public readonly eventName = 'DotnetVersionParseEvent';
|
||||
}
|
||||
|
|
|
@ -12,20 +12,34 @@ import path = require('path');
|
|||
import {
|
||||
CommandExecutionEvent,
|
||||
CommandExecutionNoStatusCodeWarning,
|
||||
CommandExecutionNonZeroExitFailure,
|
||||
CommandExecutionSignalSentEvent,
|
||||
CommandExecutionStatusEvent,
|
||||
CommandExecutionStdError,
|
||||
CommandExecutionStdOut,
|
||||
CommandExecutionUnderSudoEvent,
|
||||
CommandExecutionUnknownCommandExecutionAttempt,
|
||||
CommandExecutionUserAskDialogueEvent,
|
||||
CommandExecutionUserCompletedDialogueEvent,
|
||||
CommandExecutionUserRejectedPasswordRequest,
|
||||
CommandProcessesExecutionFailureNonTerminal,
|
||||
CommandProcessorExecutionBegin,
|
||||
CommandProcessorExecutionEnd,
|
||||
DotnetAlternativeCommandFoundEvent,
|
||||
DotnetCommandNotFoundEvent,
|
||||
DotnetWSLSecurityError
|
||||
DotnetLockAcquiredEvent,
|
||||
DotnetLockReleasedEvent,
|
||||
DotnetWSLSecurityError,
|
||||
SudoProcAliveCheckBegin,
|
||||
SudoProcAliveCheckEnd,
|
||||
SudoProcCommandExchangeBegin,
|
||||
SudoProcCommandExchangeEnd,
|
||||
SudoProcCommandExchangePing,
|
||||
TimeoutSudoCommandExecutionError,
|
||||
TimeoutSudoProcessSpawnerError
|
||||
} from '../EventStream/EventStreamEvents';
|
||||
import {exec} from '@vscode/sudo-prompt';
|
||||
|
||||
import * as lockfile from 'proper-lockfile';
|
||||
import { CommandExecutorCommand } from './CommandExecutorCommand';
|
||||
import { getInstallKeyFromContext } from '../Utils/InstallKeyGenerator';
|
||||
|
||||
|
@ -35,16 +49,25 @@ import { IUtilityContext } from './IUtilityContext';
|
|||
import { IVSCodeExtensionContext } from '../IVSCodeExtensionContext';
|
||||
import { IWindowDisplayWorker } from '../EventStream/IWindowDisplayWorker';
|
||||
import { IAcquisitionWorkerContext } from '../Acquisition/IAcquisitionWorkerContext';
|
||||
import { FileUtilities } from './FileUtilities';
|
||||
import { IFileUtilities } from './IFileUtilities';
|
||||
import { CommandProcessorOutput } from './CommandProcessorOutput';
|
||||
import { setTimeout } from 'timers';
|
||||
|
||||
/* tslint:disable:no-any */
|
||||
/* tslint:disable:no-string-literal */
|
||||
|
||||
export class CommandExecutor extends ICommandExecutor
|
||||
{
|
||||
private pathTroubleshootingOption = 'Troubleshoot';
|
||||
private sudoProcessCommunicationDir = path.join(__dirname, 'install scripts');
|
||||
private fileUtil : IFileUtilities;
|
||||
private hasEverLaunchedSudoFork = false;
|
||||
|
||||
constructor(context : IAcquisitionWorkerContext | null, utilContext : IUtilityContext)
|
||||
constructor(context : IAcquisitionWorkerContext | null, utilContext : IUtilityContext, protected readonly validSudoCommands? : string[])
|
||||
{
|
||||
super(context, utilContext);
|
||||
this.fileUtil = new FileUtilities();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -69,6 +92,7 @@ export class CommandExecutor extends ICommandExecutor
|
|||
{
|
||||
const fullCommandString = CommandExecutor.prettifyCommandExecutorCommand(command, false);
|
||||
this.context?.eventStream.post(new CommandExecutionUnderSudoEvent(`The command ${fullCommandString} is being ran under sudo.`));
|
||||
const shellScript = path.join(this.sudoProcessCommunicationDir, 'interprocess-communicator.sh');
|
||||
|
||||
if(this.isRunningUnderWSL())
|
||||
{
|
||||
|
@ -84,62 +108,285 @@ Please install the .NET SDK manually by following https://learn.microsoft.com/en
|
|||
throw err.error;
|
||||
}
|
||||
|
||||
// We wrap the exec in a promise because there is no synchronous version of the sudo exec command for vscode/sudo
|
||||
return new Promise<string>((resolve, reject) =>
|
||||
const oldReturnStatusSetting = this.returnStatus;
|
||||
this.returnStatus = true;
|
||||
const masterSudoProcessSpawnResult = this.startupSudoProc(fullCommandString, shellScript, terminalFailure);
|
||||
this.returnStatus = oldReturnStatusSetting;
|
||||
|
||||
await this.sudoProcIsLive(terminalFailure);
|
||||
return this.executeSudoViaProcessCommunication(fullCommandString, terminalFailure);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param fullCommandString the command that will be run by the master process once it is spawned, not super relevant here, used for logging.
|
||||
* @param shellScriptPath the path of the shell script file for the process to run that should loop and follow the protocol procedure
|
||||
* @param terminalFailure whether if we cannot start the sudo process, should we fail the entire program.
|
||||
* @returns The string result of either trying to spawn the sudo master process, or the status code of that attempt depending on the return mode.
|
||||
*/
|
||||
private async startupSudoProc(fullCommandString : string, shellScriptPath : string, terminalFailure : boolean) : Promise<string>
|
||||
{
|
||||
if(this.hasEverLaunchedSudoFork)
|
||||
{
|
||||
// The '.' character is not allowed for sudo-prompt so we use 'NET'
|
||||
let sanitizedCallerName = this.context?.acquisitionContext?.requestingExtensionId?.replace(/[^0-9a-z]/gi, ''); // Remove non-alphanumerics per OS requirements
|
||||
sanitizedCallerName = sanitizedCallerName?.substring(0, 69); // 70 Characters is the maximum limit we can use for the prompt.
|
||||
const options = { name: `${sanitizedCallerName ?? '.NET Install Tool'}` };
|
||||
|
||||
this.context?.eventStream.post(new CommandExecutionUserAskDialogueEvent(`Prompting user for command ${fullCommandString} under sudo.`));
|
||||
exec((fullCommandString), options, (error?: any, stdout?: any, stderr?: any) =>
|
||||
if(await this.sudoProcIsLive(false))
|
||||
{
|
||||
let commandResultString = '';
|
||||
return Promise.resolve('0');
|
||||
}
|
||||
}
|
||||
this.hasEverLaunchedSudoFork = true;
|
||||
|
||||
if (stdout)
|
||||
{
|
||||
this.context?.eventStream.post(new CommandExecutionStdOut(`The command ${fullCommandString} encountered stdout, continuing
|
||||
// Launch the process under sudo
|
||||
this.context?.eventStream.post(new CommandExecutionUserAskDialogueEvent(`Prompting user for command ${fullCommandString} under sudo.`));
|
||||
|
||||
// The '.' character is not allowed for sudo-prompt so we use 'NET'
|
||||
let sanitizedCallerName = this.context?.acquisitionContext?.requestingExtensionId?.replace(/[^0-9a-z]/gi, ''); // Remove non-alphanumerics per OS requirements
|
||||
sanitizedCallerName = sanitizedCallerName?.substring(0, 69); // 70 Characters is the maximum limit we can use for the prompt.
|
||||
const options = { name: `${sanitizedCallerName ?? 'NET Install Tool'}` };
|
||||
|
||||
fs.chmodSync(shellScriptPath, 0o500);
|
||||
exec((`"${shellScriptPath}" "${this.sudoProcessCommunicationDir}" ${this.validSudoCommands?.join(' ')} &`), options, (error?: any, stdout?: any, stderr?: any) =>
|
||||
{
|
||||
let commandResultString = '';
|
||||
|
||||
if (stdout)
|
||||
{
|
||||
this.context?.eventStream.post(new CommandExecutionStdOut(`The process spawn: ${fullCommandString} encountered stdout, continuing
|
||||
${stdout}`));
|
||||
commandResultString += stdout;
|
||||
}
|
||||
if (stderr)
|
||||
{
|
||||
this.context?.eventStream.post(new CommandExecutionStdError(`The command ${fullCommandString} encountered stderr, continuing
|
||||
commandResultString += stdout;
|
||||
}
|
||||
if (stderr)
|
||||
{
|
||||
this.context?.eventStream.post(new CommandExecutionStdError(`The process spawn: ${fullCommandString} encountered stderr, continuing
|
||||
${stderr}`));
|
||||
commandResultString += stderr;
|
||||
}
|
||||
commandResultString += stderr;
|
||||
}
|
||||
|
||||
if (error)
|
||||
if (error)
|
||||
{
|
||||
this.context?.eventStream.post(new CommandExecutionUserCompletedDialogueEvent(`The process spawn: ${fullCommandString} failed to run under sudo.`));
|
||||
if(terminalFailure)
|
||||
{
|
||||
this.context?.eventStream.post(new CommandExecutionUserCompletedDialogueEvent(`The command ${fullCommandString} failed to run under sudo.`));
|
||||
if(terminalFailure)
|
||||
if(error.code === 126)
|
||||
{
|
||||
if(error.code === 126)
|
||||
{
|
||||
const err = new CommandExecutionUserRejectedPasswordRequest(new Error(`Cancelling .NET Install, as command ${fullCommandString} failed.
|
||||
const cancelledErr = new CommandExecutionUserRejectedPasswordRequest(new Error(`Cancelling .NET Install, as command ${fullCommandString} failed.
|
||||
The user refused the password prompt.`),
|
||||
getInstallKeyFromContext(this.context?.acquisitionContext!));
|
||||
this.context?.eventStream.post(err);
|
||||
reject(err.error);
|
||||
}
|
||||
reject(error);
|
||||
getInstallKeyFromContext(this.context?.acquisitionContext!));
|
||||
this.context?.eventStream.post(cancelledErr);
|
||||
return Promise.reject(cancelledErr.error);
|
||||
}
|
||||
else
|
||||
else if(error.code === 111777)
|
||||
{
|
||||
resolve(this.returnStatus ? '1' : stderr);
|
||||
const securityErr = new CommandExecutionUnknownCommandExecutionAttempt(new Error(`Cancelling .NET Install, as command ${fullCommandString} is UNKNOWN.
|
||||
Please report this at https://github.com/dotnet/vscode-dotnet-runtime/issues.`),
|
||||
getInstallKeyFromContext(this.context?.acquisitionContext!));
|
||||
this.context?.eventStream.post(securityErr);
|
||||
return Promise.reject(securityErr.error);
|
||||
}
|
||||
return Promise.reject(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
this.context?.eventStream.post(new CommandExecutionUserCompletedDialogueEvent(`The command ${fullCommandString} successfully ran under sudo.`));
|
||||
resolve(this.returnStatus ? '0' : commandResultString);
|
||||
return Promise.resolve(this.returnStatus ? '1' : stderr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.context?.eventStream.post(new CommandExecutionUserCompletedDialogueEvent(`The process spawn: ${fullCommandString} successfully ran under sudo.`));
|
||||
return Promise.resolve(this.returnStatus ? '0' : commandResultString);
|
||||
}
|
||||
});
|
||||
|
||||
return Promise.resolve('0');
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param errorIfDead set this to true if we should terminally fail if the master process is not yet alive
|
||||
* @returns a boolean, true if the master process is live, false otherwise
|
||||
*/
|
||||
private async sudoProcIsLive(errorIfDead : boolean) : Promise<boolean>
|
||||
{
|
||||
let isLive = false;
|
||||
|
||||
const processAliveOkSentinelFile = path.join(this.sudoProcessCommunicationDir, 'ok.txt');
|
||||
const fakeLockFile = path.join(this.sudoProcessCommunicationDir, 'fakeLockFile'); // We need a file to lock the directory in the API besides the dir lock file
|
||||
|
||||
await this.fileUtil.writeFileOntoDisk('', fakeLockFile, false, this.context?.eventStream!);
|
||||
|
||||
// Prepare to lock directory
|
||||
const directoryLock = 'dir.lock';
|
||||
const directoryLockPath = path.join(path.dirname(processAliveOkSentinelFile), directoryLock);
|
||||
|
||||
// Lock the directory -- this is not a system wide lock, only a library lock we must respect in the code.
|
||||
// This will allow the process to still edit the directory, but not our extension API calls from overlapping with one another.
|
||||
await lockfile.lock(fakeLockFile, { lockfilePath: directoryLockPath, retries: { retries: 10, maxTimeout: 1000 } } )
|
||||
.then(async (release: () => void) =>
|
||||
{
|
||||
this.context?.eventStream.post(new DotnetLockAcquiredEvent(`Lock Acquired.`, new Date().toISOString(), directoryLockPath, fakeLockFile));
|
||||
|
||||
await this.fileUtil.wipeDirectory(this.sudoProcessCommunicationDir, this.context?.eventStream, ['.txt']);
|
||||
|
||||
await this.fileUtil.writeFileOntoDisk('', processAliveOkSentinelFile, true, this.context?.eventStream);
|
||||
this.context?.eventStream.post(new SudoProcAliveCheckBegin(`Looking for Sudo Process Master, wrote OK file. ${new Date().toISOString()}`));
|
||||
|
||||
const waitTime = this.context?.timeoutSeconds ? ((this.context?.timeoutSeconds/3) * 1000) : 180000;
|
||||
await this.loopWithTimeoutOnCond(100, waitTime,
|
||||
function processRespondedByDeletingOkFile() : boolean { return !fs.existsSync(processAliveOkSentinelFile) },
|
||||
function setProcessIsAlive() : void { isLive = true; }
|
||||
)
|
||||
.catch(error =>
|
||||
{
|
||||
// Let the rejected promise get handled below
|
||||
});
|
||||
|
||||
|
||||
this.context?.eventStream.post(new DotnetLockReleasedEvent(`Lock about to be released.`, new Date().toISOString(), directoryLockPath, fakeLockFile));
|
||||
return release();
|
||||
});
|
||||
|
||||
this.context?.eventStream.post(new SudoProcAliveCheckEnd(`Finished Sudo Process Master: Is Alive? ${isLive}. ${new Date().toISOString()}`));
|
||||
|
||||
if(!isLive && errorIfDead)
|
||||
{
|
||||
const err = new TimeoutSudoProcessSpawnerError(new Error(`We are unable to spawn the process to run commands under sudo for installing .NET.
|
||||
Process Directory: ${this.sudoProcessCommunicationDir} failed with error mode: ${errorIfDead}.
|
||||
It had previously spawned: ${this.hasEverLaunchedSudoFork}.`), getInstallKeyFromContext(this.context?.acquisitionContext));
|
||||
this.context?.eventStream.post(err);
|
||||
throw err.error;
|
||||
}
|
||||
|
||||
return isLive;
|
||||
}
|
||||
|
||||
private async loopWithTimeoutOnCond(sampleRatePerMs : number, durationToWaitBeforeTimeoutMs : number, conditionToStop : () => boolean, doAfterStop : () => void )
|
||||
{
|
||||
return new Promise(async (resolve, reject) =>
|
||||
{
|
||||
for (let i = 0; i < (durationToWaitBeforeTimeoutMs / sampleRatePerMs); i++)
|
||||
{
|
||||
if(conditionToStop())
|
||||
{
|
||||
doAfterStop();
|
||||
return resolve('The promise succeeded.');
|
||||
}
|
||||
this.context?.eventStream.post(new SudoProcCommandExchangePing(`Ping : Waiting. ${new Date().toISOString()}`));
|
||||
await new Promise(waitAndResolve => setTimeout(waitAndResolve, sampleRatePerMs));
|
||||
}
|
||||
|
||||
return reject('The promise timed out.');
|
||||
});
|
||||
}
|
||||
|
||||
public async executeMultipleCommands(commands: CommandExecutorCommand[], options?: any, terminalFailure = true): Promise<string[]> {
|
||||
/**
|
||||
*
|
||||
* @param commandToExecuteString The command to tell the sudo'd master process to execute. It must be live.
|
||||
* @param terminalFailure Whether to fail if we never get a response from the sudo process.
|
||||
* @param failOnNonZeroExit Whether to fail if we get an exit code from the command besides 0.
|
||||
* @returns The output string of the command, or the string status code, depending on the mode of execution.
|
||||
*/
|
||||
private async executeSudoViaProcessCommunication(commandToExecuteString : string, terminalFailure : boolean, failOnNonZeroExit = true) : Promise<string>
|
||||
{
|
||||
let commandOutputJson : CommandProcessorOutput | null = null;
|
||||
let statusCode = '1220'; // Special failure code for if code is never set error
|
||||
let commandResultString = '';
|
||||
|
||||
const commandFile = path.join(this.sudoProcessCommunicationDir, 'command.txt');
|
||||
const stderrFile = path.join(this.sudoProcessCommunicationDir, 'stderr.txt');
|
||||
const stdoutFile = path.join(this.sudoProcessCommunicationDir, 'stdout.txt');
|
||||
const statusFile = path.join(this.sudoProcessCommunicationDir, 'status.txt');
|
||||
|
||||
const outputFile = path.join(this.sudoProcessCommunicationDir, 'output.txt');
|
||||
const fakeLockFile = path.join(this.sudoProcessCommunicationDir, 'fakeLockFile'); // We need a file to lock the directory in the API besides the dir lock file
|
||||
|
||||
await this.fileUtil.writeFileOntoDisk('', fakeLockFile, false, this.context?.eventStream!);
|
||||
|
||||
// Prepare to lock directory
|
||||
const directoryLock = 'dir.lock';
|
||||
const directoryLockPath = path.join(path.dirname(commandFile), directoryLock);
|
||||
|
||||
// Lock the directory -- this is not a system wide lock, only a library lock we must respect in the code.
|
||||
// This will allow the process to still edit the directory, but not our extension API calls from overlapping with one another.
|
||||
|
||||
|
||||
await lockfile.lock(fakeLockFile, { lockfilePath: directoryLockPath, retries: { retries: 10, maxTimeout: 1000 } } )
|
||||
.then(async (release: () => any) =>
|
||||
{
|
||||
this.context?.eventStream.post(new DotnetLockAcquiredEvent(`Lock Acquired.`, new Date().toISOString(), directoryLockPath, fakeLockFile));
|
||||
await this.fileUtil.wipeDirectory(this.sudoProcessCommunicationDir, this.context?.eventStream, ['.txt', '.json']);
|
||||
|
||||
await this.fileUtil.writeFileOntoDisk(`${commandToExecuteString}`, commandFile, true, this.context?.eventStream!);
|
||||
this.context?.eventStream.post(new SudoProcCommandExchangeBegin(`Handing command off to master process. ${new Date().toISOString()}`));
|
||||
this.context?.eventStream.post(new CommandProcessorExecutionBegin(`The command ${commandToExecuteString} was forwarded to the master process to run.`));
|
||||
|
||||
|
||||
const waitTime = this.context?.timeoutSeconds ? (this.context?.timeoutSeconds * 1000) : 600000;
|
||||
await this.loopWithTimeoutOnCond(100, waitTime,
|
||||
function ProcessFinishedExecutingAndWroteOutput() : boolean { return fs.existsSync(outputFile) },
|
||||
function doNothing() : void { ; }
|
||||
)
|
||||
.catch(error =>
|
||||
{
|
||||
// Let the rejected promise get handled below
|
||||
});
|
||||
|
||||
commandOutputJson = {
|
||||
stdout : (fs.readFileSync(stdoutFile, 'utf8')).trim(),
|
||||
stderr : (fs.readFileSync(stderrFile, 'utf8')).trim(),
|
||||
status : (fs.readFileSync(statusFile, 'utf8')).trim()
|
||||
} as CommandProcessorOutput;
|
||||
this.context?.eventStream.post(new DotnetLockReleasedEvent(`Lock about to be released.`, new Date().toISOString(), directoryLockPath, fakeLockFile));
|
||||
await this.fileUtil.wipeDirectory(this.sudoProcessCommunicationDir, this.context?.eventStream, ['.txt']);
|
||||
|
||||
return release();
|
||||
});
|
||||
|
||||
this.context?.eventStream.post(new SudoProcCommandExchangeEnd(`Finished or timed out with master process. ${new Date().toISOString()}`));
|
||||
|
||||
if(!commandOutputJson && terminalFailure)
|
||||
{
|
||||
const err = new TimeoutSudoCommandExecutionError(new Error(`Timeout: The master process with command ${commandToExecuteString} never finished executing.
|
||||
Process Directory: ${this.sudoProcessCommunicationDir} failed with error mode: ${terminalFailure}.
|
||||
It had previously spawned: ${this.hasEverLaunchedSudoFork}.`), getInstallKeyFromContext(this.context?.acquisitionContext));
|
||||
this.context?.eventStream.post(err);
|
||||
throw err.error;
|
||||
}
|
||||
else if(!commandOutputJson)
|
||||
{
|
||||
this.context?.eventStream.post(new CommandProcessesExecutionFailureNonTerminal(`The command ${commandToExecuteString} never finished under the process, but it was marked non terminal.`));
|
||||
}
|
||||
else
|
||||
{
|
||||
this.context?.eventStream.post(new CommandProcessorExecutionEnd(`The command ${commandToExecuteString} was finished by the master process, as ${outputFile} was found.`));
|
||||
const stdout = commandOutputJson['stdout'];
|
||||
const stderr = commandOutputJson['stderr'];
|
||||
statusCode = commandOutputJson['status'];
|
||||
if (stdout)
|
||||
{
|
||||
this.context?.eventStream.post(new CommandExecutionStdOut(`The command ${commandToExecuteString} encountered stdout, continuing
|
||||
${stdout}`));
|
||||
commandResultString += stdout;
|
||||
}
|
||||
if (stderr)
|
||||
{
|
||||
this.context?.eventStream.post(new CommandExecutionStdError(`The command ${commandToExecuteString} encountered stderr, continuing
|
||||
${stderr}`));
|
||||
commandResultString += stderr;
|
||||
}
|
||||
|
||||
if(statusCode !== '0' && failOnNonZeroExit)
|
||||
{
|
||||
const err = new CommandExecutionNonZeroExitFailure(new Error(`Cancelling .NET Install, as command ${commandToExecuteString} returned with status ${statusCode}.`),
|
||||
getInstallKeyFromContext(this.context?.acquisitionContext!));
|
||||
this.context?.eventStream.post(err);
|
||||
throw err.error;
|
||||
}
|
||||
}
|
||||
|
||||
return (this.returnStatus ? statusCode : commandResultString);
|
||||
}
|
||||
|
||||
public async executeMultipleCommands(commands: CommandExecutorCommand[], options?: any, terminalFailure = true): Promise<string[]>
|
||||
{
|
||||
const results = [];
|
||||
for(const command of commands)
|
||||
{
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/* --------------------------------------------------------------------------------------------
|
||||
* Licensed to the .NET Foundation under one or more agreements.
|
||||
* The .NET Foundation licenses this file to you under the MIT license.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
export type CommandProcessorOutput =
|
||||
{
|
||||
/**
|
||||
* @property commandRoot
|
||||
* The stdout of the command.
|
||||
* @property commandParts
|
||||
* The stderr of the command.
|
||||
* @property status
|
||||
* The exit code of the program/command after execution.
|
||||
*/
|
||||
stdout : string,
|
||||
stderr : string,
|
||||
status : string
|
||||
}
|
|
@ -3,229 +3,244 @@
|
|||
* The .NET Foundation licenses this file to you under the MIT license.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
import * as eol from 'eol';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import * as proc from 'child_process';
|
||||
import * as crypto from 'crypto';
|
||||
import * as eol from 'eol';
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import * as os from 'os';
|
||||
import * as proc from 'child_process';
|
||||
import * as crypto from 'crypto';
|
||||
import { IFileUtilities } from './IFileUtilities';
|
||||
import * as lockfile from 'proper-lockfile';
|
||||
import * as lockfile from 'proper-lockfile';
|
||||
import { IEventStream } from '../EventStream/EventStream';
|
||||
import { DotnetCommandFallbackArchitectureEvent,
|
||||
DotnetCommandFallbackOSEvent,
|
||||
DotnetFileWriteRequestEvent,
|
||||
DotnetLockAcquiredEvent,
|
||||
DotnetLockAttemptingAcquireEvent,
|
||||
DotnetLockErrorEvent,
|
||||
DotnetLockReleasedEvent,
|
||||
SuppressedAcquisitionError
|
||||
DotnetCommandFallbackOSEvent,
|
||||
DotnetFileWriteRequestEvent,
|
||||
DotnetLockAcquiredEvent,
|
||||
DotnetLockAttemptingAcquireEvent,
|
||||
DotnetLockErrorEvent,
|
||||
DotnetLockReleasedEvent,
|
||||
SuppressedAcquisitionError
|
||||
} from '../EventStream/EventStreamEvents';
|
||||
/* tslint:disable:no-any */
|
||||
|
||||
export class FileUtilities extends IFileUtilities
|
||||
{
|
||||
public async writeFileOntoDisk(scriptContent: string, filePath: string, eventStream : IEventStream)
|
||||
{
|
||||
eventStream.post(new DotnetFileWriteRequestEvent(`Request to write`, new Date().toISOString(), filePath));
|
||||
public async writeFileOntoDisk(scriptContent: string, filePath: string, alreadyHoldingLock = false, eventStream? : IEventStream)
|
||||
{
|
||||
eventStream?.post(new DotnetFileWriteRequestEvent(`Request to write`, new Date().toISOString(), filePath));
|
||||
|
||||
if (!fs.existsSync(path.dirname(filePath))) {
|
||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||
}
|
||||
// Prepare to lock directory so we can check file exists atomically
|
||||
const directoryLock = 'dir.lock';
|
||||
const directoryLockPath = path.join(path.dirname(filePath), directoryLock);
|
||||
if (!fs.existsSync(path.dirname(filePath))) {
|
||||
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
||||
}
|
||||
// Prepare to lock directory so we can check file exists atomically
|
||||
const directoryLock = 'dir.lock';
|
||||
const directoryLockPath = path.join(path.dirname(filePath), directoryLock);
|
||||
|
||||
// Begin Critical Section
|
||||
// This check is part of a RACE CONDITION, it is technically part of the critical section as you will fail if the file DNE,
|
||||
// but you cant lock the file until it exists. Since there is no context in which files written by this are deleted while this can run,
|
||||
// theoretically, this ok. The library SHOULD provide a RAII based system for locks, but it does not.
|
||||
if(!fs.existsSync(filePath))
|
||||
{
|
||||
// Create an empty file, as proper-lockfile fails to lock a file if file dne
|
||||
eventStream.post(new DotnetFileWriteRequestEvent(`File did not exist upon write request.`, new Date().toISOString(), filePath));
|
||||
fs.writeFileSync(filePath, '');
|
||||
}
|
||||
// Begin Critical Section
|
||||
// This check is part of a RACE CONDITION, it is technically part of the critical section as you will fail if the file DNE,
|
||||
// but you cant lock the file until it exists. Since there is no context in which files written by this are deleted while this can run,
|
||||
// theoretically, this ok. The library SHOULD provide a RAII based system for locks, but it does not.
|
||||
if(!fs.existsSync(filePath))
|
||||
{
|
||||
// Create an empty file, as proper-lockfile fails to lock a file if file dne
|
||||
eventStream?.post(new DotnetFileWriteRequestEvent(`File did not exist upon write request.`, new Date().toISOString(), filePath));
|
||||
fs.writeFileSync(filePath, '');
|
||||
}
|
||||
|
||||
eventStream.post(new DotnetLockAttemptingAcquireEvent(`Lock Acquisition request to begin.`, new Date().toISOString(), directoryLockPath, filePath));
|
||||
await lockfile.lock(filePath, { lockfilePath: directoryLockPath, retries: { retries: 10, maxTimeout: 1000 } } )
|
||||
.then(async (release) =>
|
||||
{
|
||||
eventStream.post(new DotnetLockAcquiredEvent(`Lock Acquired.`, new Date().toISOString(), directoryLockPath, filePath));
|
||||
if(!alreadyHoldingLock)
|
||||
{
|
||||
eventStream?.post(new DotnetLockAttemptingAcquireEvent(`Lock Acquisition request to begin.`, new Date().toISOString(), directoryLockPath, filePath));
|
||||
await lockfile.lock(filePath, { lockfilePath: directoryLockPath, retries: { retries: 10, maxTimeout: 1000 } } )
|
||||
.then(async (release) =>
|
||||
{
|
||||
eventStream?.post(new DotnetLockAcquiredEvent(`Lock Acquired.`, new Date().toISOString(), directoryLockPath, filePath));
|
||||
|
||||
// We would like to unlock the directory, but we can't grab a lock on the file if the directory is locked.
|
||||
// Theoretically you could: add a new file-writer lock as a 3rd party lock ...
|
||||
// Then, lock the file-writer, unlock the directory, then lock the file, then unlock file-writer, ...
|
||||
// operate, then unlock file once the operation is done.
|
||||
// For now, keep the entire directory locked.
|
||||
// We would like to unlock the directory, but we can't grab a lock on the file if the directory is locked.
|
||||
// Theoretically you could: add a new file-writer lock as a 3rd party lock ...
|
||||
// Then, lock the file-writer, unlock the directory, then lock the file, then unlock file-writer, ...
|
||||
// operate, then unlock file once the operation is done.
|
||||
// For now, keep the entire directory locked.
|
||||
|
||||
scriptContent = eol.auto(scriptContent);
|
||||
const existingScriptContent = fs.readFileSync(filePath).toString();
|
||||
// fs.writeFile will replace the file if it exists.
|
||||
// https://nodejs.org/api/fs.html#fswritefilefile-data-options-callback
|
||||
if(scriptContent !== existingScriptContent)
|
||||
{
|
||||
fs.writeFileSync(filePath, scriptContent);
|
||||
eventStream.post(new DotnetFileWriteRequestEvent(`File content needed to be updated.`, new Date().toISOString(), filePath));
|
||||
}
|
||||
else
|
||||
{
|
||||
eventStream.post(new DotnetFileWriteRequestEvent(`File content is an exact match, not writing file.`, new Date().toISOString(), filePath));
|
||||
}
|
||||
this.innerWriteFile(scriptContent, filePath, eventStream);
|
||||
|
||||
fs.chmodSync(filePath, 0o744);
|
||||
eventStream.post(new DotnetLockReleasedEvent(`Lock about to be released.`, new Date().toISOString(), directoryLockPath, filePath));
|
||||
return release();
|
||||
})
|
||||
.catch((e : Error) =>
|
||||
{
|
||||
// Either the lock could not be acquired or releasing it failed
|
||||
eventStream.post(new DotnetLockErrorEvent(e, e.message, new Date().toISOString(), directoryLockPath, filePath));
|
||||
});
|
||||
// End Critical Section
|
||||
}
|
||||
eventStream?.post(new DotnetLockReleasedEvent(`Lock about to be released.`, new Date().toISOString(), directoryLockPath, filePath));
|
||||
return release();
|
||||
})
|
||||
.catch((e : Error) =>
|
||||
{
|
||||
// Either the lock could not be acquired or releasing it failed
|
||||
eventStream?.post(new DotnetLockErrorEvent(e, e.message, new Date().toISOString(), directoryLockPath, filePath));
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
this.innerWriteFile(scriptContent, filePath, eventStream);
|
||||
}
|
||||
// End Critical Section
|
||||
}
|
||||
|
||||
/**
|
||||
* @param directoryToWipe the directory to delete all of the files in if privilege to do so exists.
|
||||
*/
|
||||
public wipeDirectory(directoryToWipe : string, eventStream : IEventStream)
|
||||
{
|
||||
if(!fs.existsSync(directoryToWipe))
|
||||
{
|
||||
return;
|
||||
}
|
||||
private innerWriteFile(scriptContent: string, filePath: string, eventStream? : IEventStream)
|
||||
{
|
||||
scriptContent = eol.auto(scriptContent);
|
||||
const existingScriptContent = fs.readFileSync(filePath).toString();
|
||||
// fs.writeFile will replace the file if it exists.
|
||||
// https://nodejs.org/api/fs.html#fswritefilefile-data-options-callback
|
||||
if(scriptContent !== existingScriptContent)
|
||||
{
|
||||
fs.writeFileSync(filePath, scriptContent);
|
||||
eventStream?.post(new DotnetFileWriteRequestEvent(`File content needed to be updated.`, new Date().toISOString(), filePath));
|
||||
}
|
||||
else
|
||||
{
|
||||
eventStream?.post(new DotnetFileWriteRequestEvent(`File content is an exact match, not writing file.`, new Date().toISOString(), filePath));
|
||||
}
|
||||
|
||||
// Use rimraf to delete all of the items in a directory without the directory itself.
|
||||
fs.readdirSync(directoryToWipe).forEach(f =>
|
||||
{
|
||||
try
|
||||
{
|
||||
fs.rmSync(`${directoryToWipe}/${f}`);
|
||||
}
|
||||
catch(error : any)
|
||||
{
|
||||
eventStream.post(new SuppressedAcquisitionError(error, `Failed to delete ${f} when marked for deletion.`));
|
||||
}
|
||||
});
|
||||
}
|
||||
fs.chmodSync(filePath, 0o744);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param nodeArchitecture the architecture in node style string of what to install
|
||||
* @returns the architecture in the style that .net / the .net install scripts expect
|
||||
*
|
||||
* Node - amd64 is documented as an option for install scripts but its no longer used.
|
||||
* s390x is also no longer used.
|
||||
* ppc64le is supported but this version of node has no distinction of the endianness of the process.
|
||||
* It has no mapping to mips or other node architectures.
|
||||
*
|
||||
* @remarks Falls back to string 'auto' if a mapping does not exist which is not a valid architecture.
|
||||
*/
|
||||
public nodeArchToDotnetArch(nodeArchitecture : string, eventStream : IEventStream)
|
||||
{
|
||||
switch(nodeArchitecture)
|
||||
{
|
||||
case 'x64': {
|
||||
return nodeArchitecture;
|
||||
}
|
||||
case 'ia32': {
|
||||
return 'x86';
|
||||
}
|
||||
case 'x86': {
|
||||
// In case the function is called twice
|
||||
return 'x86';
|
||||
}
|
||||
case 'arm': {
|
||||
return nodeArchitecture;
|
||||
}
|
||||
case 'arm64': {
|
||||
return nodeArchitecture;
|
||||
}
|
||||
case 's390x': {
|
||||
return 's390x';
|
||||
}
|
||||
default: {
|
||||
eventStream.post(new DotnetCommandFallbackArchitectureEvent(`The architecture ${os.arch()} of the platform is unexpected, falling back to auto-arch.`));
|
||||
return 'auto';
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* @param directoryToWipe the directory to delete all of the files in if privilege to do so exists.
|
||||
* @param fileExtensionsToDelete - if undefined, delete all files. if not, delete only files with extensions in this array in lower case.
|
||||
*/
|
||||
public wipeDirectory(directoryToWipe : string, eventStream? : IEventStream, fileExtensionsToDelete? : string[])
|
||||
{
|
||||
if(!fs.existsSync(directoryToWipe))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param nodeOS the OS in node style string of what to install
|
||||
* @returns the OS in the style that .net / the .net install scripts expect
|
||||
*
|
||||
*/
|
||||
public nodeOSToDotnetOS(nodeOS : string, eventStream : IEventStream)
|
||||
{
|
||||
switch(nodeOS)
|
||||
{
|
||||
case 'win32': {
|
||||
return 'win';
|
||||
}
|
||||
case 'darwin': {
|
||||
return 'osx';
|
||||
}
|
||||
case 'linux': {
|
||||
return nodeOS;
|
||||
}
|
||||
default: {
|
||||
eventStream.post(new DotnetCommandFallbackOSEvent(`The OS ${os.platform()} of the platform is unexpected, falling back to auto-os.`));
|
||||
return 'auto'
|
||||
}
|
||||
}
|
||||
}
|
||||
// Use rimraf to delete all of the items in a directory without the directory itself.
|
||||
fs.readdirSync(directoryToWipe).forEach(f =>
|
||||
{
|
||||
try
|
||||
{
|
||||
if(!fileExtensionsToDelete || path.extname(f).toLocaleLowerCase() in fileExtensionsToDelete)
|
||||
fs.rmSync(`${directoryToWipe}/${f}`);
|
||||
}
|
||||
catch(error : any)
|
||||
{
|
||||
eventStream?.post(new SuppressedAcquisitionError(error, `Failed to delete ${f} when marked for deletion.`));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @returns true if the process is running with admin privileges
|
||||
*/
|
||||
public isElevated(eventStream? : IEventStream) : boolean
|
||||
{
|
||||
if(os.platform() !== 'win32')
|
||||
{
|
||||
try
|
||||
{
|
||||
const commandResult = proc.spawnSync('id', ['-u']);
|
||||
return commandResult.status === 0;
|
||||
}
|
||||
catch(error : any)
|
||||
{
|
||||
eventStream?.post(new SuppressedAcquisitionError(error, `Failed to run 'id' to check for privilege, running without privilege.`))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param nodeArchitecture the architecture in node style string of what to install
|
||||
* @returns the architecture in the style that .net / the .net install scripts expect
|
||||
*
|
||||
* Node - amd64 is documented as an option for install scripts but its no longer used.
|
||||
* s390x is also no longer used.
|
||||
* ppc64le is supported but this version of node has no distinction of the endianness of the process.
|
||||
* It has no mapping to mips or other node architectures.
|
||||
*
|
||||
* @remarks Falls back to string 'auto' if a mapping does not exist which is not a valid architecture.
|
||||
*/
|
||||
public nodeArchToDotnetArch(nodeArchitecture : string, eventStream : IEventStream)
|
||||
{
|
||||
switch(nodeArchitecture)
|
||||
{
|
||||
case 'x64': {
|
||||
return nodeArchitecture;
|
||||
}
|
||||
case 'ia32': {
|
||||
return 'x86';
|
||||
}
|
||||
case 'x86': {
|
||||
// In case the function is called twice
|
||||
return 'x86';
|
||||
}
|
||||
case 'arm': {
|
||||
return nodeArchitecture;
|
||||
}
|
||||
case 'arm64': {
|
||||
return nodeArchitecture;
|
||||
}
|
||||
case 's390x': {
|
||||
return 's390x';
|
||||
}
|
||||
default: {
|
||||
eventStream.post(new DotnetCommandFallbackArchitectureEvent(`The architecture ${os.arch()} of the platform is unexpected, falling back to auto-arch.`));
|
||||
return 'auto';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
// If we can execute this command on Windows then we have admin rights.
|
||||
proc.execFileSync( 'net', ['session'], { 'stdio': 'ignore' } );
|
||||
return true;
|
||||
}
|
||||
catch ( error : any )
|
||||
{
|
||||
eventStream?.post(new SuppressedAcquisitionError(error, `Failed to run 'net' to check for privilege, running without privilege.`))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
/**
|
||||
*
|
||||
* @param nodeOS the OS in node style string of what to install
|
||||
* @returns the OS in the style that .net / the .net install scripts expect
|
||||
*
|
||||
*/
|
||||
public nodeOSToDotnetOS(nodeOS : string, eventStream : IEventStream)
|
||||
{
|
||||
switch(nodeOS)
|
||||
{
|
||||
case 'win32': {
|
||||
return 'win';
|
||||
}
|
||||
case 'darwin': {
|
||||
return 'osx';
|
||||
}
|
||||
case 'linux': {
|
||||
return nodeOS;
|
||||
}
|
||||
default: {
|
||||
eventStream.post(new DotnetCommandFallbackOSEvent(`The OS ${os.platform()} of the platform is unexpected, falling back to auto-os.`));
|
||||
return 'auto'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private sha512Hasher(filePath : string)
|
||||
{
|
||||
return new Promise<string>((resolve, reject) =>
|
||||
{
|
||||
const hash = crypto.createHash('sha512');
|
||||
const fileStream = fs.createReadStream(filePath);
|
||||
fileStream.on('error', err => reject(err));
|
||||
fileStream.on('data', chunk => hash.update(chunk));
|
||||
fileStream.on('end', () => resolve(hash.digest('hex')));
|
||||
})
|
||||
};
|
||||
/**
|
||||
*
|
||||
* @returns true if the process is running with admin privileges
|
||||
*/
|
||||
public isElevated(eventStream? : IEventStream) : boolean
|
||||
{
|
||||
if(os.platform() !== 'win32')
|
||||
{
|
||||
try
|
||||
{
|
||||
const commandResult = proc.spawnSync('id', ['-u']);
|
||||
return commandResult.status === 0;
|
||||
}
|
||||
catch(error : any)
|
||||
{
|
||||
eventStream?.post(new SuppressedAcquisitionError(error, `Failed to run 'id' to check for privilege, running without privilege.`))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public async getFileHash(filePath : string) : Promise<string | null>
|
||||
{
|
||||
const res = await this.sha512Hasher(filePath);
|
||||
return res;
|
||||
}
|
||||
try
|
||||
{
|
||||
// If we can execute this command on Windows then we have admin rights.
|
||||
proc.execFileSync( 'net', ['session'], { 'stdio': 'ignore' } );
|
||||
return true;
|
||||
}
|
||||
catch ( error : any )
|
||||
{
|
||||
eventStream?.post(new SuppressedAcquisitionError(error, `Failed to run 'net' to check for privilege, running without privilege.`))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private sha512Hasher(filePath : string)
|
||||
{
|
||||
return new Promise<string>((resolve, reject) =>
|
||||
{
|
||||
const hash = crypto.createHash('sha512');
|
||||
const fileStream = fs.createReadStream(filePath);
|
||||
fileStream.on('error', err => reject(err));
|
||||
fileStream.on('data', chunk => hash.update(chunk));
|
||||
fileStream.on('end', () => resolve(hash.digest('hex')));
|
||||
})
|
||||
};
|
||||
|
||||
public async getFileHash(filePath : string) : Promise<string | null>
|
||||
{
|
||||
const res = await this.sha512Hasher(filePath);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,12 +8,12 @@ import { IEventStream } from '../EventStream/EventStream';
|
|||
|
||||
export abstract class IFileUtilities
|
||||
{
|
||||
public abstract writeFileOntoDisk(scriptContent: string, filePath: string, eventStream : IEventStream) : void;
|
||||
public abstract writeFileOntoDisk(scriptContent: string, filePath: string, alreadyHoldingLock : boolean, eventStream? : IEventStream) : void;
|
||||
|
||||
/**
|
||||
* @param directoryToWipe the directory to delete all of the files in if privilege to do so exists.
|
||||
*/
|
||||
public abstract wipeDirectory(directoryToWipe : string, eventStream : IEventStream) : void;
|
||||
public abstract wipeDirectory(directoryToWipe : string, eventStream? : IEventStream, fileExtensionsToDelete? : string[]) : void;
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -335,6 +335,7 @@ export class MockCommandExecutor extends ICommandExecutor
|
|||
|
||||
if(!command.runUnderSudo && this.fakeReturnValue === '')
|
||||
{
|
||||
this.trueExecutor.returnStatus = this.returnStatus;
|
||||
return this.trueExecutor.execute(command, options);
|
||||
}
|
||||
else if(this.otherCommandsToMock.some(x => x.includes(command.commandRoot)))
|
||||
|
@ -368,14 +369,14 @@ export class MockFileUtilities extends IFileUtilities
|
|||
{
|
||||
private trueUtilities = new FileUtilities();
|
||||
|
||||
public writeFileOntoDisk(content : string, filePath : string)
|
||||
public writeFileOntoDisk(content : string, filePath : string, alreadyHoldingLock = false)
|
||||
{
|
||||
return this.trueUtilities.writeFileOntoDisk(content, filePath, new MockEventStream());
|
||||
return this.trueUtilities.writeFileOntoDisk(content, filePath, alreadyHoldingLock, new MockEventStream());
|
||||
}
|
||||
|
||||
public wipeDirectory(directoryToWipe : string, eventSteam : IEventStream)
|
||||
public wipeDirectory(directoryToWipe : string, eventSteam : IEventStream, fileExtensionsToDelete? : string[])
|
||||
{
|
||||
return this.trueUtilities.wipeDirectory(directoryToWipe, eventSteam);
|
||||
return this.trueUtilities.wipeDirectory(directoryToWipe, eventSteam, fileExtensionsToDelete);
|
||||
}
|
||||
|
||||
public isElevated()
|
||||
|
@ -480,7 +481,7 @@ export class MockDistroProvider extends IDistroDotnetSDKProvider
|
|||
return new GenericDistroSDKProvider(this.distroVersion, this.context, getMockUtilityContext()).JsonDotnetVersion(fullySpecifiedDotnetVersion);
|
||||
}
|
||||
|
||||
protected isPackageFoundInSearch(resultOfSearchCommand: any): boolean {
|
||||
protected isPackageFoundInSearch(resultOfSearchCommand: any, searchCommandExitCode : string): boolean {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ Microsoft.NETCore.App 7.0.5 [/usr/lib/dotnet/shared/Microsoft.NETCore.App]`;
|
|||
if(shouldRun)
|
||||
{
|
||||
await provider.getInstalledGlobalDotnetPathIfExists(installType);
|
||||
assert.equal(mockExecutor.attemptedCommand, 'which dotnet');
|
||||
assert.equal(mockExecutor.attemptedCommand, 'readlink -f /usr/bin/dotnet');
|
||||
}
|
||||
}).timeout(standardTimeoutTime);
|
||||
|
||||
|
@ -127,15 +127,15 @@ Microsoft.NETCore.App 7.0.5 [/usr/lib/dotnet/shared/Microsoft.NETCore.App]`;
|
|||
if(shouldRun)
|
||||
{
|
||||
const recVersion = await provider.getRecommendedDotnetVersion(installType);
|
||||
assert.equal(mockExecutor.attemptedCommand, 'apt-cache search dotnet-sdk-7.0');
|
||||
assert.equal(recVersion, '7.0.1xx');
|
||||
assert.equal(mockExecutor.attemptedCommand, 'dotnet --version', 'Searched for the newest package last with regex');
|
||||
assert.equal(recVersion, '8.0.1xx', 'Resolved the most recent available version : will eventually break if the mock data is not updated');
|
||||
}
|
||||
}).timeout(standardTimeoutTime);
|
||||
|
||||
test('Gives Correct Version Support Info', async () => {
|
||||
if(shouldRun)
|
||||
{
|
||||
let supported = await provider.isDotnetVersionSupported('8.0.101', installType);
|
||||
let supported = await provider.isDotnetVersionSupported('11.0.101', installType);
|
||||
// In the mock data, 8.0 is not supported, so it should be false.
|
||||
assert.equal(supported, false);
|
||||
supported = await provider.isDotnetVersionSupported('7.0.101', installType);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
import * as chai from 'chai';
|
||||
import * as os from 'os';
|
||||
import { MockCommandExecutor, MockEventStream } from '../mocks/MockObjects';
|
||||
import { DistroVersionPair, DotnetDistroSupportStatus } from '../../Acquisition/LinuxVersionResolver';
|
||||
import { DistroVersionPair, DotnetDistroSupportStatus, LinuxVersionResolver } from '../../Acquisition/LinuxVersionResolver';
|
||||
import { getMockAcquisitionContext, getMockUtilityContext } from './TestUtility';
|
||||
import { LinuxInstallType } from '../../Acquisition/LinuxInstallType';
|
||||
import { RedHatDistroSDKProvider } from '../../Acquisition/RedHatDistroSDKProvider';
|
||||
|
@ -18,7 +18,8 @@ const acquisitionContext = getMockAcquisitionContext(false, mockVersion);
|
|||
const mockExecutor = new MockCommandExecutor(acquisitionContext, getMockUtilityContext());
|
||||
const pair : DistroVersionPair = { distro : 'Red Hat Enterprise Linux', version : '9.0' };
|
||||
const provider : RedHatDistroSDKProvider = new RedHatDistroSDKProvider(pair, acquisitionContext, getMockUtilityContext(), mockExecutor);
|
||||
const shouldRun = os.platform() === 'linux';
|
||||
const versionResolver = new LinuxVersionResolver(acquisitionContext, getMockUtilityContext(), acquisitionContext.acquisitionContext!, mockExecutor);
|
||||
let shouldRun = os.platform() === 'linux';
|
||||
const installType : LinuxInstallType = 'sdk';
|
||||
const noDotnetString = `
|
||||
Command 'dotnet' not found, but can be installed with:
|
||||
|
@ -33,11 +34,13 @@ Command 'dotnet' not found, but can be installed with:
|
|||
suite('Red Hat For Linux Distro Logic Unit Tests', () =>
|
||||
{
|
||||
test('Package Check Succeeds', async () => {
|
||||
shouldRun = os.platform() === 'linux' && (await versionResolver.getRunningDistro()).distro === 'Red Hat Enterprise Linux';
|
||||
|
||||
if(shouldRun)
|
||||
{
|
||||
// assert this passes : we don't want the test to be reliant on machine state for whether the package exists or not, so don't check output
|
||||
await provider.dotnetPackageExistsOnSystem(mockVersion, installType);
|
||||
assert.equal(mockExecutor.attemptedCommand, 'yum list install dotnet-sdk-7.0 -q');
|
||||
assert.equal(mockExecutor.attemptedCommand, 'yum list install dotnet-sdk-9.0 -q');
|
||||
}
|
||||
}).timeout(standardTimeoutTime);
|
||||
|
||||
|
@ -104,7 +107,7 @@ Microsoft.NETCore.App 7.0.5 [/usr/lib/dotnet/shared/Microsoft.NETCore.App]`;
|
|||
if(shouldRun)
|
||||
{
|
||||
await provider.getInstalledGlobalDotnetPathIfExists(installType);
|
||||
assert.equal(mockExecutor.attemptedCommand, 'which dotnet');
|
||||
assert.equal(mockExecutor.attemptedCommand, 'readlink -f /usr/bin/dotnet');
|
||||
}
|
||||
}).timeout(standardTimeoutTime);
|
||||
|
||||
|
@ -127,15 +130,15 @@ Microsoft.NETCore.App 7.0.5 [/usr/lib/dotnet/shared/Microsoft.NETCore.App]`;
|
|||
if(shouldRun)
|
||||
{
|
||||
const recVersion = await provider.getRecommendedDotnetVersion(installType);
|
||||
assert.equal(mockExecutor.attemptedCommand, 'yum search dotnet-sdk-7.0 -q');
|
||||
assert.equal(recVersion, '7.0.1xx');
|
||||
assert.equal(mockExecutor.attemptedCommand, 'dotnet --version', 'Correct command run to get recommended version, uses newest package in distro json');
|
||||
assert.equal(recVersion, '8.0.1xx', 'The most in support version is suggested : will eventually break if not updated');
|
||||
}
|
||||
}).timeout(standardTimeoutTime);
|
||||
|
||||
test('Gives Correct Version Support Info', async () => {
|
||||
if(shouldRun)
|
||||
{
|
||||
let supported = await provider.isDotnetVersionSupported('8.0.101', installType);
|
||||
let supported = await provider.isDotnetVersionSupported('11.0.101', installType);
|
||||
// In the mock data, 8.0 is not supported, so it should be false.
|
||||
assert.equal(supported, false);
|
||||
supported = await provider.isDotnetVersionSupported('7.0.101', installType);
|
||||
|
|
Загрузка…
Ссылка в новой задаче