Retry loading uri if it fails with a 5xx error code. (#3980)

* Log read file error

* Add changes

* Refactor

* Retries

* Retries

* update

* Wip

* Move chaching cache system to datastore

* Append

* Remove old test

* File not found

* Defined errors for fs

* Wip

* Bump @azure-tools/uri

* Real file sytem test

* Add remote calls tests

* Update changelog
This commit is contained in:
Timothee Guerin 2021-03-15 11:04:39 -07:00 коммит произвёл GitHub
Родитель 27c01f3d5e
Коммит 5a47e7dbc2
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
25 изменённых файлов: 435 добавлений и 225 удалений

Просмотреть файл

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@autorest/configuration",
"comment": "Extract CachingFileSystem out into @azure-tools/datastore",
"type": "minor"
}
],
"packageName": "@autorest/configuration",
"email": "tiguerin@microsoft.com"
}

Просмотреть файл

@ -0,0 +1,11 @@
{
"changes": [
{
"packageName": "@autorest/core",
"comment": "",
"type": "none"
}
],
"packageName": "@autorest/core",
"email": "tiguerin@microsoft.com"
}

Просмотреть файл

@ -0,0 +1,16 @@
{
"changes": [
{
"packageName": "@azure-tools/datastore",
"comment": "Added retry logic for loading uris.",
"type": "minor"
},
{
"packageName": "@azure-tools/datastore",
"comment": "**Refactor** abstract file system. Moved CachingFileSystem from @autorest/configuration.",
"type": "minor"
}
],
"packageName": "@azure-tools/datastore",
"email": "tiguerin@microsoft.com"
}

Просмотреть файл

@ -4,7 +4,7 @@ dependencies:
'@azure-tools/linq': 3.1.262
'@azure-tools/object-comparison': 3.0.252
'@azure-tools/tasks': 3.0.253
'@azure-tools/uri': 3.0.255
'@azure-tools/uri': 3.0.256
'@rush-temp/autorest': file:projects/autorest.tgz_ts-node@9.1.1+webpack-cli@4.4.0
'@rush-temp/codegen': file:projects/codegen.tgz_prettier@2.2.1+ts-node@9.1.1
'@rush-temp/codemodel': file:projects/codemodel.tgz_prettier@2.2.1
@ -37,7 +37,7 @@ dependencies:
'@types/mocha': 5.2.7
'@types/morgan': 1.9.2
'@types/mustache': 4.1.1
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/npm-package-arg': 6.1.0
'@types/semver': 5.5.0
'@types/source-map': 0.5.0
@ -146,7 +146,7 @@ packages:
node: '>=10.12.0'
resolution:
integrity: sha512-ViYOxgal9iukwbebZUpj5hEnT6OjSLDFItqPXYfMkntm7BCM1OQbBVo49KMBqOyCu6o+M5EVC7KF8SldL3oGtg==
/@azure-tools/uri/3.0.255:
/@azure-tools/uri/3.0.256:
dependencies:
'@azure-tools/async-io': 3.0.253
file-url: 2.0.2
@ -156,7 +156,7 @@ packages:
engines:
node: '>=10.12.0'
resolution:
integrity: sha512-UX0pDOVwN/wSABGOG+9KwGTvca+JcyVTJ8KA/Kz9kHZCbdvgN3bE+uu1f51ANfSfz7ksPKDqpUwmncDyYsFtkA==
integrity: sha512-DrOybrLHzGC/wbdhn9T2OxcR66x/6bm2M9AGb0CKdhAIN8OMcGdv51PoXc0EYXupCx8naIgpvcw585MMx4uW8w==
/@babel/code-frame/7.12.11:
dependencies:
'@babel/highlight': 7.13.10
@ -545,7 +545,7 @@ packages:
/@jest/console/26.6.2:
dependencies:
'@jest/types': 26.6.2
'@types/node': 14.14.33
'@types/node': 14.14.34
chalk: 4.1.0
jest-message-util: 26.6.2
jest-util: 26.6.2
@ -562,7 +562,7 @@ packages:
'@jest/test-result': 26.6.2
'@jest/transform': 26.6.2
'@jest/types': 26.6.2
'@types/node': 14.14.33
'@types/node': 14.14.34
ansi-escapes: 4.3.1
chalk: 4.1.0
exit: 0.1.2
@ -596,7 +596,7 @@ packages:
dependencies:
'@jest/fake-timers': 26.6.2
'@jest/types': 26.6.2
'@types/node': 14.14.33
'@types/node': 14.14.34
jest-mock: 26.6.2
dev: false
engines:
@ -607,7 +607,7 @@ packages:
dependencies:
'@jest/types': 26.6.2
'@sinonjs/fake-timers': 6.0.1
'@types/node': 14.14.33
'@types/node': 14.14.34
jest-message-util: 26.6.2
jest-mock: 26.6.2
jest-util: 26.6.2
@ -656,7 +656,7 @@ packages:
engines:
node: '>= 10.14.2'
optionalDependencies:
node-notifier: 8.0.1
node-notifier: 8.0.2
resolution:
integrity: sha512-h2bW53APG4HvkOnVMo8q3QXa6pcaNt1HkwVsOPMBV6LD/q9oSpxNSYZQYkAnjdMjrJ86UuYeLo+aEZClV6opnw==
/@jest/source-map/26.6.2:
@ -720,7 +720,7 @@ packages:
dependencies:
'@types/istanbul-lib-coverage': 2.0.3
'@types/istanbul-reports': 3.0.0
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/yargs': 15.0.13
chalk: 4.1.0
dev: false
@ -815,7 +815,7 @@ packages:
/@types/body-parser/1.19.0:
dependencies:
'@types/connect': 3.4.34
'@types/node': 14.14.33
'@types/node': 14.14.34
dev: false
resolution:
integrity: sha512-W98JrE0j2K78swW4ukqMleo8R7h/pFETjM2DQ90MF6XK2i4LO4W3gQ71Lt4w3bfm2EvVSyWHplECvB5sK22yFQ==
@ -829,7 +829,7 @@ packages:
integrity: sha512-7koSjp08QxKoS1/+3T15+kD7+vqOUvZRHvM8PutF3Xsk5aAEkdlIGRsHJ3/XsC3izoqTwBdRW/vH7rzCKkIicA==
/@types/connect/3.4.34:
dependencies:
'@types/node': 14.14.33
'@types/node': 14.14.34
dev: false
resolution:
integrity: sha512-ePPA/JuI+X0vb+gSWlPKOY0NdNAie/rPUqX2GUPpbZwiKTkSPhjXWuee47E4MtE54QVzGCQMQkAL6JhV2E1+cQ==
@ -865,7 +865,7 @@ packages:
integrity: sha512-laIjwTQaD+5DukBZaygQ79K1Z0jb1bPEMRrkXSLjtCcZm+abyp5YbrqpSLzD42FwWW6gK/aS4NYpJ804nG2brg==
/@types/express-serve-static-core/4.17.18:
dependencies:
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/qs': 6.9.6
'@types/range-parser': 1.2.3
dev: false
@ -883,13 +883,13 @@ packages:
/@types/glob/7.1.3:
dependencies:
'@types/minimatch': 3.0.3
'@types/node': 14.14.33
'@types/node': 14.14.34
dev: false
resolution:
integrity: sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w==
/@types/graceful-fs/4.1.5:
dependencies:
'@types/node': 14.14.33
'@types/node': 14.14.34
dev: false
resolution:
integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==
@ -950,7 +950,7 @@ packages:
integrity: sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==
/@types/morgan/1.9.2:
dependencies:
'@types/node': 14.14.33
'@types/node': 14.14.34
dev: false
resolution:
integrity: sha512-edtGMEdit146JwwIeyQeHHg9yID4WSolQPxpEorHmN3KuytuCHyn2ELNr5Uxy8SerniFbbkmgKMrGM933am5BQ==
@ -958,10 +958,10 @@ packages:
dev: false
resolution:
integrity: sha512-Sm0NWeLhS2QL7NNGsXvO+Fgp7e3JLHCO6RS3RCnfjAnkw6Y1bsji/AGfISdQZDIR/AeOyzkrxRk9jBkl55zdJw==
/@types/node/14.14.33:
/@types/node/14.14.34:
dev: false
resolution:
integrity: sha512-oJqcTrgPUF29oUP8AsUqbXGJNuPutsetaa9kTQAQce5Lx5dTYWV02ScBiT/k1BX/Z7pKeqedmvp39Wu4zR7N7g==
integrity: sha512-dBPaxocOK6UVyvhbnpFIj2W+S+1cBTkHQbFQfeeJhoKFbzYcVUGHvddeWPSucKATb3F0+pgDq0i6ghEaZjsugA==
/@types/normalize-package-data/2.4.0:
dev: false
resolution:
@ -989,7 +989,7 @@ packages:
/@types/serve-static/1.13.9:
dependencies:
'@types/mime': 1.3.2
'@types/node': 14.14.33
'@types/node': 14.14.34
dev: false
resolution:
integrity: sha512-ZFqF6qa48XsPdjXV5Gsz0Zqmux2PerNd3a/ktL45mHpa19cuMi/cL8tcxdAx497yRh+QtYPuofjT9oWw9P7nkA==
@ -1014,7 +1014,7 @@ packages:
/@types/superagent/4.1.10:
dependencies:
'@types/cookiejar': 2.1.2
'@types/node': 14.14.33
'@types/node': 14.14.34
dev: false
resolution:
integrity: sha512-xAgkb2CMWUMCyVc/3+7iQfOEBE75NvuZeezvmixbUw3nmENf2tCnQkW5yQLTYqvXUQ+R6EXxdqKKbal2zM5V/g==
@ -1036,7 +1036,7 @@ packages:
integrity: sha512-EGkrJD5Uy+Pg0NUR8uA4bJ5WMfljyad0G+784vLCNUkD+QwOJXUbBYExXfVGf7YtyzdQp3L/XMYcliB987kL5Q==
/@types/webpack-sources/2.1.0:
dependencies:
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/source-list-map': 0.1.2
source-map: 0.7.3
dev: false
@ -1045,7 +1045,7 @@ packages:
/@types/webpack/4.41.26:
dependencies:
'@types/anymatch': 1.3.1
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/tapable': 1.0.6
'@types/uglify-js': 3.13.0
'@types/webpack-sources': 2.1.0
@ -1877,9 +1877,9 @@ packages:
integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==
/browserslist/4.16.3:
dependencies:
caniuse-lite: 1.0.30001198
caniuse-lite: 1.0.30001199
colorette: 1.2.2
electron-to-chromium: 1.3.685
electron-to-chromium: 1.3.687
escalade: 3.1.1
node-releases: 1.1.71
dev: false
@ -2003,10 +2003,10 @@ packages:
node: '>=10'
resolution:
integrity: sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==
/caniuse-lite/1.0.30001198:
/caniuse-lite/1.0.30001199:
dev: false
resolution:
integrity: sha512-r5GGgESqOPZzwvdLVER374FpQu2WluCF1Z2DSiFJ89KSmGjT0LVKjgv4NcAqHmGWF9ihNpqRI9KXO9Ex4sKsgA==
integrity: sha512-ifbK2eChUCFUwGhlEzIoVwzFt1+iriSjyKKFYNfv6hN34483wyWpLLavYQXhnR036LhkdUYaSDpHg1El++VgHQ==
/capture-exit/2.0.0:
dependencies:
rsvp: 4.8.5
@ -2721,10 +2721,10 @@ packages:
dev: false
resolution:
integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=
/electron-to-chromium/1.3.685:
/electron-to-chromium/1.3.687:
dev: false
resolution:
integrity: sha512-C3oFZNkJ8lz85ADqr3hzpjBc2ciejMRN2SCd/D0hwcqpr6MGxfdN/j89VN6l+ERTuCUvhg0VYsf40Q4qTz4bhQ==
integrity: sha512-IpzksdQNl3wdgkzf7dnA7/v10w0Utf1dF2L+B4+gKrloBrxCut+au+kky3PYvle3RMdSxZP+UiCZtLbcYRxSNQ==
/emittery/0.7.2:
dev: false
engines:
@ -4737,7 +4737,7 @@ packages:
'@jest/environment': 26.6.2
'@jest/fake-timers': 26.6.2
'@jest/types': 26.6.2
'@types/node': 14.14.33
'@types/node': 14.14.34
jest-mock: 26.6.2
jest-util: 26.6.2
jsdom: 16.5.0
@ -4751,7 +4751,7 @@ packages:
'@jest/environment': 26.6.2
'@jest/fake-timers': 26.6.2
'@jest/types': 26.6.2
'@types/node': 14.14.33
'@types/node': 14.14.34
jest-mock: 26.6.2
jest-util: 26.6.2
dev: false
@ -4769,7 +4769,7 @@ packages:
dependencies:
'@jest/types': 26.6.2
'@types/graceful-fs': 4.1.5
'@types/node': 14.14.33
'@types/node': 14.14.34
anymatch: 3.1.1
fb-watchman: 2.0.1
graceful-fs: 4.2.6
@ -4794,7 +4794,7 @@ packages:
'@jest/source-map': 26.6.2
'@jest/test-result': 26.6.2
'@jest/types': 26.6.2
'@types/node': 14.14.33
'@types/node': 14.14.34
chalk: 4.1.0
co: 4.6.0
expect: 26.6.2
@ -4853,7 +4853,7 @@ packages:
/jest-mock/26.6.2:
dependencies:
'@jest/types': 26.6.2
'@types/node': 14.14.33
'@types/node': 14.14.34
dev: false
engines:
node: '>= 10.14.2'
@ -4909,7 +4909,7 @@ packages:
'@jest/environment': 26.6.2
'@jest/test-result': 26.6.2
'@jest/types': 26.6.2
'@types/node': 14.14.33
'@types/node': 14.14.34
chalk: 4.1.0
emittery: 0.7.2
exit: 0.1.2
@ -4971,7 +4971,7 @@ packages:
integrity: sha512-lrzyR3N8sacTAMeonbqpnSka1dHNux2uk0qqDXVkMv2c/A3wYnvQ4EXuI013Y6+gSKSCxdaczvf4HF0mVXHRdw==
/jest-serializer/26.6.2:
dependencies:
'@types/node': 14.14.33
'@types/node': 14.14.34
graceful-fs: 4.2.6
dev: false
engines:
@ -5004,7 +5004,7 @@ packages:
/jest-util/26.6.2:
dependencies:
'@jest/types': 26.6.2
'@types/node': 14.14.33
'@types/node': 14.14.34
chalk: 4.1.0
graceful-fs: 4.2.6
is-ci: 2.0.0
@ -5031,7 +5031,7 @@ packages:
dependencies:
'@jest/test-result': 26.6.2
'@jest/types': 26.6.2
'@types/node': 14.14.33
'@types/node': 14.14.34
ansi-escapes: 4.3.1
chalk: 4.1.0
jest-util: 26.6.2
@ -5043,7 +5043,7 @@ packages:
integrity: sha512-WKJob0P/Em2csiVthsI68p6aGKTIcsfjH9Gsx1f0A3Italz43e3ho0geSAVsmj09RWOELP1AZ/DXyJgOgDKxXQ==
/jest-worker/26.6.2:
dependencies:
'@types/node': 14.14.33
'@types/node': 14.14.34
merge-stream: 2.0.0
supports-color: 7.2.0
dev: false
@ -5904,7 +5904,7 @@ packages:
node: '>=0.10.0'
resolution:
integrity: sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=
/node-notifier/8.0.1:
/node-notifier/8.0.2:
dependencies:
growly: 1.3.0
is-wsl: 2.2.0
@ -5915,7 +5915,7 @@ packages:
dev: false
optional: true
resolution:
integrity: sha512-BvEXF+UmsnAfYfoapKM9nGxnP+Wn7P91YfXmrKnfcYCx6VBeoN5Ez5Ogck6I8Bi5k4RlpqRYaw75pAwzX9OphA==
integrity: sha512-oJP/9NAdd9+x2Q+rfphB2RJCHjod70RcRLjosiPMMu5gjIfwVnOUGq2nbTjTUbmy0DJ/tFIVT30+Qe3nzl4TJg==
/node-releases/1.1.71:
dev: false
resolution:
@ -9002,10 +9002,10 @@ packages:
dependencies:
'@azure-tools/async-io': 3.0.253
'@azure-tools/tasks': 3.0.253
'@azure-tools/uri': 3.0.255
'@azure-tools/uri': 3.0.256
'@types/commonmark': 0.27.4
'@types/jest': 26.0.20
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/semver': 5.5.0
'@types/webpack': 4.41.26
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
@ -9044,7 +9044,7 @@ packages:
'@azure-tools/linq': 3.1.262
'@types/jest': 26.0.20
'@types/js-yaml': 4.0.0
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/semver': 5.5.0
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
@ -9073,7 +9073,7 @@ packages:
dependencies:
'@azure-tools/linq': 3.1.262
'@types/js-yaml': 4.0.0
'@types/node': 14.14.33
'@types/node': 14.14.34
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
eslint: 7.21.0
@ -9098,7 +9098,7 @@ packages:
dependencies:
'@types/commonmark': 0.27.4
'@types/jest': 26.0.20
'@types/node': 14.14.33
'@types/node': 14.14.34
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
commonmark: 0.27.0
@ -9124,7 +9124,7 @@ packages:
'@types/diff': 4.0.2
'@types/js-yaml': 4.0.0
'@types/mocha': 5.2.7
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/source-map-support': 0.5.3
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
@ -9155,10 +9155,10 @@ packages:
file:projects/configuration.tgz_prettier@2.2.1+ts-node@9.1.1:
dependencies:
'@azure-tools/async-io': 3.0.253
'@azure-tools/uri': 3.0.255
'@azure-tools/uri': 3.0.256
'@types/jest': 26.0.20
'@types/lodash': 4.14.168
'@types/node': 14.14.33
'@types/node': 14.14.34
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
eslint: 7.21.0
@ -9186,12 +9186,12 @@ packages:
'@azure-tools/linq': 3.1.262
'@azure-tools/object-comparison': 3.0.252
'@azure-tools/tasks': 3.0.253
'@azure-tools/uri': 3.0.255
'@azure-tools/uri': 3.0.256
'@types/commonmark': 0.27.4
'@types/jest': 26.0.20
'@types/jsonpath': 0.2.0
'@types/lodash': 4.14.168
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/source-map': 0.5.0
'@types/webpack': 4.41.26
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
@ -9239,10 +9239,10 @@ packages:
dependencies:
'@azure-tools/linq': 3.1.262
'@azure-tools/tasks': 3.0.253
'@azure-tools/uri': 3.0.255
'@azure-tools/uri': 3.0.256
'@types/jest': 26.0.20
'@types/jsonpath': 0.2.0
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/source-map': 0.5.0
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
@ -9274,7 +9274,7 @@ packages:
'@azure-tools/object-comparison': 3.0.252
'@azure-tools/tasks': 3.0.253
'@types/jest': 26.0.20
'@types/node': 14.14.33
'@types/node': 14.14.34
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
compare-versions: 3.6.0
@ -9298,7 +9298,7 @@ packages:
file:projects/extension-base.tgz_prettier@2.2.1:
dependencies:
'@types/js-yaml': 4.0.0
'@types/node': 14.14.33
'@types/node': 14.14.34
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
eslint: 7.21.0
@ -9325,7 +9325,7 @@ packages:
'@azure-tools/tasks': 3.0.253
'@types/command-exists': 1.2.0
'@types/jest': 26.0.20
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/npm-package-arg': 6.1.0
'@types/semver': 5.5.0
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
@ -9369,7 +9369,7 @@ packages:
'@types/js-yaml': 4.0.0
'@types/morgan': 1.9.2
'@types/mustache': 4.1.1
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/supertest': 2.0.10
'@types/yargs': 15.0.13
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
@ -9408,9 +9408,9 @@ packages:
'@azure-tools/async-io': 3.0.253
'@azure-tools/linq': 3.1.262
'@azure-tools/tasks': 3.0.253
'@azure-tools/uri': 3.0.255
'@azure-tools/uri': 3.0.256
'@types/jest': 26.0.20
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/webpack': 4.41.26
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
@ -9442,7 +9442,7 @@ packages:
dependencies:
'@types/jest': 26.0.20
'@types/js-yaml': 4.0.0
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/source-map': 0.5.0
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
@ -9469,7 +9469,7 @@ packages:
file:projects/openapi.tgz_prettier@2.2.1+ts-node@9.1.1:
dependencies:
'@types/jest': 26.0.20
'@types/node': 14.14.33
'@types/node': 14.14.34
'@typescript-eslint/eslint-plugin': 4.17.0_3641211d697b4d4d12940eb9cf33dc28
'@typescript-eslint/parser': 4.17.0_eslint@7.21.0+typescript@4.2.3
eslint: 7.21.0
@ -9498,7 +9498,7 @@ packages:
version: 0.0.0
file:projects/test-public-packages.tgz_prettier@2.2.1:
dependencies:
'@types/node': 14.14.33
'@types/node': 14.14.34
'@types/source-map-support': 0.5.3
eslint: 7.21.0
eslint-plugin-prettier: 3.2.0_eslint@7.21.0+prettier@2.2.1

Просмотреть файл

@ -630,7 +630,7 @@ class OpenApiLanguageService extends TextDocuments implements IFileSystem {
}
}
// IFileSystem Implementation
public async EnumerateFileUris(folderUri: string): Promise<Array<string>> {
public async list(folderUri: string): Promise<Array<string>> {
if (folderUri && folderUri.startsWith("file:")) {
const folderPath = FileUriToPath(folderUri);
if (await isDirectory(folderPath)) {
@ -648,7 +648,7 @@ class OpenApiLanguageService extends TextDocuments implements IFileSystem {
return [];
}
public async ReadFile(fileUri: string): Promise<string> {
public async read(fileUri: string): Promise<string> {
const doc = this.get(fileUri) || this.virtualFile.get(fileUri);
try {
if (doc) {
@ -662,6 +662,14 @@ class OpenApiLanguageService extends TextDocuments implements IFileSystem {
throw new Error(`Unable to read ${fileUri}`);
}
public async EnumerateFileUris(folderUri: string): Promise<Array<string>> {
return this.list(folderUri);
}
public async ReadFile(fileUri: string): Promise<string> {
return this.read(fileUri);
}
private async process(configurationUrl: string) {
const result = this.results.get(configurationUrl) || new Result(this, configurationUrl);
this.results.set(configurationUrl, result);

Просмотреть файл

@ -194,11 +194,11 @@ export class AutoRest extends EventEmitter {
export async function LiterateToJson(content: string): Promise<string> {
try {
const autorest = new AutoRest({
async EnumerateFileUris(folderUri: string): Promise<Array<string>> {
return [];
},
ReadFile: async (f: string): Promise<string> =>
f == "none:///empty-file.md" ? content || "# empty file" : "# empty file",
list: () => Promise.resolve([]),
read: (f: string) => Promise.resolve(f == "none:///empty-file.md" ? content || "# empty file" : "# empty file"),
EnumerateFileUris: () => Promise.resolve([]),
ReadFile: (f: string) =>
Promise.resolve(f == "none:///empty-file.md" ? content || "# empty file" : "# empty file"),
});
let result = "";
autorest.AddConfiguration({ "input-file": "none:///empty-file.md", "output-artifact": ["swagger-document"] });

Просмотреть файл

@ -3,7 +3,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IFileSystem, LazyPromise, RealFileSystem } from "@azure-tools/datastore";
import { CachingFileSystem, IFileSystem, LazyPromise, RealFileSystem } from "@azure-tools/datastore";
import { Extension, ExtensionManager } from "@azure-tools/extension";
import { CreateFolderUri, ResolveUri } from "@azure-tools/uri";
import { join } from "path";
@ -11,7 +11,6 @@ import { AutoRestExtension } from "../pipeline/plugin-endpoint";
import {
AutorestConfiguration,
AutorestRawConfiguration,
CachingFileSystem,
ConfigurationLoader,
getNestedConfiguration,
mergeConfigurations,

Просмотреть файл

@ -1,15 +1,10 @@
import { DataStore } from "@azure-tools/datastore";
import { DataStore, CachingFileSystem } from "@azure-tools/datastore";
import { clone } from "@azure-tools/linq";
import { From } from "linq-es2015";
import { basename, dirname } from "path";
import { CancellationToken, CancellationTokenSource } from "vscode-jsonrpc";
import { Artifact } from "../artifact";
import {
CachingFileSystem,
getNestedConfiguration,
ResolvedDirective,
resolveDirectives,
} from "@autorest/configuration";
import { getNestedConfiguration, ResolvedDirective, resolveDirectives } from "@autorest/configuration";
import { MessageEmitter } from "./message-emitter";
import { IEvent } from "../events";
import {

Просмотреть файл

@ -1,19 +0,0 @@
import { MemoryFileSystem } from "@azure-tools/datastore";
import assert from "assert";
describe("FileSystemTests", () => {
it("does async iterable work", async () => {
const f = new MemoryFileSystem(
new Map<string, string>([
["readme.md", "# this is a test\n see https://aka.ms/autorest"],
["other.md", "#My Doc."],
]),
);
let n = 0;
for (const name of await f.EnumerateFileUris()) {
n++;
}
assert.equal(n, 2);
assert.equal(await f.ReadFile(MemoryFileSystem.DefaultVirtualRootUri + "other.md"), "#My Doc.");
});
});

Просмотреть файл

@ -1,9 +1,8 @@
import { DataStore, IFileSystem, RealFileSystem } from "@azure-tools/datastore";
import { DataStore, IFileSystem, RealFileSystem, CachingFileSystem } from "@azure-tools/datastore";
import { Extension, ExtensionManager, LocalExtension } from "@azure-tools/extension";
import { CreateFileUri, ResolveUri, simplifyUri, FileUriToPath } from "@azure-tools/uri";
import { AutorestLogger } from "@autorest/common";
import untildify from "untildify";
import { CachingFileSystem } from "../caching-file-system";
import { AutorestConfiguration } from "../autorest-configuration";
import { detectConfigurationFile } from "../configuration-file-resolver";
import { ConfigurationManager, readConfigurationFile } from "../configuration-manager";

Просмотреть файл

@ -1,6 +1,5 @@
export * from "./autorest-configuration";
export * from "./autorest-raw-configuration";
export * from "./caching-file-system";
export * from "./configuration-manager";
export * from "./configuration-file-resolver";
export * from "./configuration-loader";

Просмотреть файл

@ -145,12 +145,15 @@ class ReadThroughDataSource extends DataSource {
// populate cache
let data: string | null = null;
try {
data = (await this.fs.ReadFile(uri)) || (await ReadUri(uri));
data = (await this.fs.read(uri)) || (await ReadUri(uri));
if (data) {
const parent = ParentFolderUri(uri) || "";
// hack to let $(this-folder) resolve to the location...
data = data.replace(/\$\(this-folder\)\/*/g, parent);
}
} catch (e) {
// eslint-disable-next-line no-console
console.error("Unexpected error trying to read file", e);
} finally {
if (!data) {
// eslint-disable-next-line no-unsafe-finally

Просмотреть файл

@ -1,14 +1,14 @@
import { IFileSystem } from "@azure-tools/datastore";
import { IFileSystem } from "./file-system";
export class CachingFileSystem implements IFileSystem {
protected cache = new Map<string, string | Error>();
constructor(protected actualFileSystem: IFileSystem) {}
EnumerateFileUris(folderUri: string): Promise<Array<string>> {
return this.actualFileSystem.EnumerateFileUris(folderUri);
public list(folderUri: string): Promise<Array<string>> {
return this.actualFileSystem.list(folderUri);
}
async ReadFile(uri: string): Promise<string> {
public async read(uri: string): Promise<string> {
const content = this.cache.get(uri);
if (content !== undefined) {
if (typeof content === "string") {
@ -17,7 +17,7 @@ export class CachingFileSystem implements IFileSystem {
throw content;
}
try {
const data = await this.actualFileSystem.ReadFile(uri);
const data = await this.actualFileSystem.read(uri);
this.cache.set(uri, data);
return data;
} catch (E) {
@ -26,4 +26,18 @@ export class CachingFileSystem implements IFileSystem {
throw E;
}
}
/**
* @deprecated
*/
public EnumerateFileUris(folderUri: string): Promise<Array<string>> {
return this.list(folderUri);
}
/**
* @deprecated
*/
public async ReadFile(uri: string): Promise<string> {
return this.read(uri);
}
}

Просмотреть файл

@ -0,0 +1,38 @@
import { WriteString } from "@azure-tools/uri";
import { RealFileSystem } from "./real-file-system";
// handles:
// - GitHub URI adjustment
// - GitHub auth
/**
*
*/
export class EnhancedFileSystem extends RealFileSystem {
public constructor(private githubAuthToken?: string) {
super();
}
public async read(uri: string): Promise<string> {
return super.read(uri, this.getHeaders(uri));
}
public async write(uri: string, content: string): Promise<void> {
return WriteString(uri, content);
}
private getHeaders(uri: string) {
const headers: { [key: string]: string } = {};
// check for GitHub OAuth token
if (
this.githubAuthToken &&
(uri.startsWith("https://raw.githubusercontent.com") || uri.startsWith("https://github.com"))
) {
// eslint-disable-next-line no-console
console.error(`Used GitHub authentication token to request '${uri}'.`);
headers.authorization = `Bearer ${this.githubAuthToken}`;
}
return headers;
}
}

Просмотреть файл

@ -0,0 +1,10 @@
export class FileSystemError extends Error {}
/**
* Error representing a uri not found.
*/
export class UriNotFoundError extends FileSystemError {
public constructor(public uri: string, message?: string) {
super(message ?? `${uri} not found.`);
}
}

Просмотреть файл

@ -1,18 +0,0 @@
import { MemoryFileSystem } from "./file-system";
describe("Filesystem", () => {
it("Simple memory filesystem test", async () => {
const f = new MemoryFileSystem(
new Map<string, string>([
["readme.md", "# this is a test\n see https://aka.ms/autorest"],
["other.md", "#My Doc."],
]),
);
let n = 0;
for (const name of await f.EnumerateFileUris()) {
n++;
}
expect(n).toEqual(2);
expect(await f.ReadFile(MemoryFileSystem.DefaultVirtualRootUri + "other.md")).toEqual("#My Doc.");
});
});

Просмотреть файл

@ -1,106 +1,29 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { EnumerateFiles, ResolveUri, ReadUri, WriteString } from "@azure-tools/uri";
// import { From } from "linq-es2015";
import { items, keys } from "@azure-tools/linq";
/**
* Virtual filesystem, to find and read files.
*/
export interface IFileSystem extends ILegacyFileSystem {
/**
* Read the content of the given Uri
* @param fileUri Uri of the file.
* @throws {FileSystemError}
*/
read(fileUri: string): Promise<string>;
import * as Constants from "../constants";
/**
* List the files in the given folder.
* @param fileUri Uri of the folder.
* @throws {FileSystemError}
*/
list(folderUri: string): Promise<string[]>;
}
export interface IFileSystem {
export interface ILegacyFileSystem {
/**
* @deprecated, use @see {IFileSystem.list}
*/
EnumerateFileUris(folderUri: string): Promise<Array<string>>;
/**
* @deprecated, use @see {IFileSystem.read}
*/
ReadFile(uri: string): Promise<string>;
}
export class MemoryFileSystem implements IFileSystem {
public static readonly DefaultVirtualRootUri = "file:///";
private filesByUri: Map<string, string>;
public constructor(files: Map<string, string>) {
this.filesByUri = new Map<string, string>(
items(files).select(
(each) => [ResolveUri(MemoryFileSystem.DefaultVirtualRootUri, each.key), each.value] as [string, string],
),
);
/*
this.filesByUri = new Map<string, string>(
From(files.entries()).Select(entry => [
ResolveUri(MemoryFileSystem.DefaultVirtualRootUri, entry[0]),
entry[1]
] as [string, string]));
*/
}
public readonly Outputs: Map<string, string> = new Map<string, string>();
async ReadFile(uri: string): Promise<string> {
if (!this.filesByUri.has(uri)) {
throw new Error(`File ${uri} is not in the MemoryFileSystem`);
}
return <string>this.filesByUri.get(uri);
}
async EnumerateFileUris(folderUri: string = MemoryFileSystem.DefaultVirtualRootUri): Promise<Array<string>> {
// return await [...From(this.filesByUri.keys()).Where(uri => {
return keys(this.filesByUri)
.where((uri) => {
// in folder?
if (!uri.startsWith(folderUri)) {
return false;
}
// not in subfolder?
// return uri.substr(folderUri.length).indexOf("/") === -1;
return uri.substr(folderUri.length).indexOf("/") === -1;
})
.toArray();
//})];
}
async WriteFile(uri: string, content: string): Promise<void> {
this.Outputs.set(uri, content);
}
}
export class RealFileSystem implements IFileSystem {
public constructor() {}
EnumerateFileUris(folderUri: string): Promise<Array<string>> {
return EnumerateFiles(folderUri, [Constants.DefaultConfiguration]);
}
async ReadFile(uri: string): Promise<string> {
return ReadUri(uri);
}
async WriteFile(uri: string, content: string): Promise<void> {
return WriteString(uri, content);
}
}
// handles:
// - GitHub URI adjustment
// - GitHub auth
export class EnhancedFileSystem implements IFileSystem {
public constructor(private githubAuthToken?: string) {}
EnumerateFileUris(folderUri: string): Promise<Array<string>> {
return EnumerateFiles(folderUri, [Constants.DefaultConfiguration]);
}
async ReadFile(uri: string): Promise<string> {
const headers: { [key: string]: string } = {};
// check for GitHub OAuth token
if (
this.githubAuthToken &&
(uri.startsWith("https://raw.githubusercontent.com") || uri.startsWith("https://github.com"))
) {
// eslint-disable-next-line no-console
console.error(`Used GitHub authentication token to request '${uri}'.`);
headers.authorization = `Bearer ${this.githubAuthToken}`;
}
return ReadUri(uri, headers);
}
async WriteFile(uri: string, content: string): Promise<void> {
return WriteString(uri, content);
}
}

Просмотреть файл

@ -0,0 +1,6 @@
export * from "./caching-file-system";
export * from "./enhanced-file-system";
export * from "./errors";
export * from "./file-system";
export * from "./memory-file-system";
export * from "./real-file-system";

Просмотреть файл

@ -0,0 +1,25 @@
import { UriNotFoundError } from "./errors";
import { MemoryFileSystem } from "./memory-file-system";
describe("MemoryFileSystem", () => {
const fs = new MemoryFileSystem(
new Map<string, string>([
["readme.md", "# this is a test\n see https://aka.ms/autorest"],
["other.md", "#My Doc."],
]),
);
it("should list files", async () => {
const files = await fs.list();
expect(files).toHaveLength(2);
});
it("should read file content", async () => {
expect(await fs.read(MemoryFileSystem.DefaultVirtualRootUri + "other.md")).toEqual("#My Doc.");
});
it("should throw error if the file doesn't exists", async () => {
const uri = MemoryFileSystem.DefaultVirtualRootUri + "unkown-file.md";
await expect(() => fs.read(uri)).rejects.toThrowError(UriNotFoundError);
});
});

Просмотреть файл

@ -0,0 +1,52 @@
import { ResolveUri } from "@azure-tools/uri";
import { UriNotFoundError } from "./errors";
import { IFileSystem } from "./file-system";
export class MemoryFileSystem implements IFileSystem {
public static readonly DefaultVirtualRootUri = "file:///";
private filesByUri: Map<string, string>;
public constructor(files: Map<string, string>) {
this.filesByUri = new Map<string, string>(
[...files.entries()].map(([uri, content]) => [ResolveUri(MemoryFileSystem.DefaultVirtualRootUri, uri), content]),
);
}
public readonly outputs: Map<string, string> = new Map<string, string>();
public async read(uri: string): Promise<string> {
const content = this.filesByUri.get(uri);
if (content === undefined) {
throw new UriNotFoundError(uri, `File ${uri} is not in the MemoryFileSystem`);
}
return content;
}
async list(folderUri: string = MemoryFileSystem.DefaultVirtualRootUri): Promise<Array<string>> {
return [...this.filesByUri.keys()].filter((uri) => {
// in folder?
if (!uri.startsWith(folderUri)) {
return false;
}
return uri.substr(folderUri.length).indexOf("/") === -1;
});
}
public async write(uri: string, content: string): Promise<void> {
this.outputs.set(uri, content);
}
/**
* @deprecated
*/
public async ReadFile(uri: string): Promise<string> {
return this.read(uri);
}
/**
* @deprecated
*/
public async EnumerateFileUris(folderUri: string = MemoryFileSystem.DefaultVirtualRootUri): Promise<Array<string>> {
return this.list(folderUri);
}
}

Просмотреть файл

@ -0,0 +1,44 @@
import { ResolveUri, CreateFileOrFolderUri } from "@azure-tools/uri";
import { join } from "path";
import { UriNotFoundError } from "./errors";
import { RealFileSystem } from "./real-file-system";
const baseDir = CreateFileOrFolderUri(join(__dirname, "../../test/resources/fake-fs"));
describe("MemoryFileSystem", () => {
const fs = new RealFileSystem();
describe("accessing load files", () => {
it("should list files", async () => {
const files = await fs.list(baseDir);
expect(files).toHaveLength(2);
});
it("should read local file content", async () => {
expect(await fs.read(ResolveUri(baseDir + "/", "foo.txt"))).toEqual("bar\n");
});
it("should throw error if the local file doesn't exists", async () => {
const uri = ResolveUri(baseDir + "/", "unkown-file.md");
await expect(() => fs.read(uri)).rejects.toThrowError(UriNotFoundError);
});
});
describe("accessing remote files", () => {
it("should looks for readme.md when listing files", async () => {
const files = await fs.list("https://github.com/Azure/autorest/blob/master/");
expect(files).toHaveLength(1);
expect(files[0]).toEqual("https://github.com/Azure/autorest/blob/master/readme.md");
});
it("should read local file content", async () => {
expect(await fs.read("https://github.com/Azure/autorest/blob/master/readme.md")).toContain("Autorest");
});
it("should throw error if the local file doesn't exists", async () => {
await expect(() =>
fs.read("https://github.com/Azure/autorest/blob/master/this-file-doesnot-exists.md"),
).rejects.toThrowError(UriNotFoundError);
});
});
});

Просмотреть файл

@ -0,0 +1,92 @@
import { EnumerateFiles, ReadUri, WriteString } from "@azure-tools/uri";
import { IFileSystem } from "./file-system";
import * as Constants from "../constants";
import { UriNotFoundError } from "./errors";
export class RealFileSystem implements IFileSystem {
public constructor() {}
public list(folderUri: string): Promise<Array<string>> {
return EnumerateFiles(folderUri, [Constants.DefaultConfiguration]);
}
public async read(uri: string, headers: { [name: string]: string } = {}): Promise<string> {
return await readUriWithRetries(uri, headers);
}
public async write(uri: string, content: string): Promise<void> {
return WriteString(uri, content);
}
/**
* @deprecated
*/
public async ReadFile(uri: string): Promise<string> {
return this.read(uri);
}
/**
* @deprecated
*/
public async EnumerateFileUris(folderUri: string): Promise<Array<string>> {
return this.list(folderUri);
}
}
const MAX_RETRY_COUNT = 3;
/**
* ReadUri with retries in the case of a remote url and retryable http error.
* @param uri uri
* @param headers optional headers for the request.
*/
export async function readUriWithRetries(uri: string, headers: { [name: string]: string } = {}): Promise<string> {
let tryed = 1;
for (;;) {
try {
return await ReadUri(uri, headers);
} catch (e) {
tryed++;
if (isRetryableStatusCode(e.statusCode) && tryed <= MAX_RETRY_COUNT) {
// eslint-disable-next-line no-console
console.error(`Failed to load uri ${uri}, trying again (${tryed}/${MAX_RETRY_COUNT})`, e);
} else {
throw processError(uri, e);
}
}
}
}
export const KnownUriErrorCode = {
NotFound: "ENOTFOUND",
};
/**
* @param statusCode Error status code.
* @returns Boolean if this request should be retried.
*/
function isRetryableStatusCode(statusCode: number): boolean {
return statusCode >= 500 || statusCode === 0;
}
/**
* Convert external errors into known error types when able.
* @param uri Uri that was loaded.
* @param error Error.
* @returns new error if error is known or the same error otherwise.
*/
function processError(uri: string, error: Error) {
if (isCodeError(error)) {
if (error.code === KnownUriErrorCode.NotFound) {
return new UriNotFoundError(uri, `${uri} is not found: ${error.message}`);
}
}
return error;
}
interface CodeError extends Error {
code: string;
}
function isCodeError(error: unknown): error is CodeError {
return typeof error === "object" && error != null && "code" in error && (error as any)["code"] != null;
}

Просмотреть файл

@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// export * from "./proxy"
export * from "./file-system/file-system";
export * from "./file-system";
export * from "./json-path/json-path";
export * from "./json-pointer";
export * from "./graph-builder";

Просмотреть файл

@ -0,0 +1 @@
bar

Просмотреть файл

@ -0,0 +1 @@
# THis is a readme