From e20647bc5fbb912b7b33e762acb85b7e0c7d92ad Mon Sep 17 00:00:00 2001 From: DarkIsDude Date: Wed, 25 Feb 2026 16:24:10 +0100 Subject: [PATCH 1/2] =?UTF-8?q?=F0=9F=9A=A8=20add=20eslint=20configuration?= =?UTF-8?q?=20to=20monitor=20async/await?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: CLDSRV-860 --- eslint.config.mjs | 6 ++ package.json | 7 +- yarn.lock | 165 +++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 175 insertions(+), 3 deletions(-) diff --git a/eslint.config.mjs b/eslint.config.mjs index 7d2efd9cb0..d647d0f2af 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -1,4 +1,6 @@ import mocha from "eslint-plugin-mocha"; +import promise from "eslint-plugin-promise"; +import n from "eslint-plugin-n"; import path from "node:path"; import { fileURLToPath } from "node:url"; import js from "@eslint/js"; @@ -15,6 +17,8 @@ const compat = new FlatCompat({ export default [...compat.extends('@scality/scality'), { plugins: { mocha, + promise, + n, }, languageOptions: { @@ -67,5 +71,7 @@ export default [...compat.extends('@scality/scality'), { "quote-props": "off", "mocha/no-exclusive-tests": "error", "no-redeclare": ["error", { "builtinGlobals": false }], + "promise/prefer-await-to-then": "warn", + "n/callback-return": "warn", }, }]; diff --git a/package.json b/package.json index 28ce78cdd2..037697c3da 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,8 @@ "eslint": "^9.14.0", "eslint-plugin-import": "^2.31.0", "eslint-plugin-mocha": "^10.5.0", + "eslint-plugin-n": "^17.24.0", + "eslint-plugin-promise": "^7.2.1", "express": "^4.21.1", "ioredis": "^5.4.1", "istanbul": "^0.4.5", @@ -79,6 +81,7 @@ "nyc": "^15.1.0", "pino-pretty": "^13.1.3", "sinon": "^13.0.1", + "ts-morph": "^27.0.2", "tv4": "^1.3.0" }, "resolutions": { @@ -140,6 +143,8 @@ "test_sur": "mocha --reporter mocha-multi-reporters --reporter-options configFile=$INIT_CWD/tests/reporter-config.json --recursive tests/sur --exit", "multiple_backend_test": "CI=true S3BACKEND=mem S3METADATA=mem S3DATA=multiple mocha --reporter mocha-multi-reporters --reporter-options configFile=$INIT_CWD/tests/reporter-config.json -t 20000 --recursive tests/multipleBackend --exit", "cover": "nyc --clean --silent yarn run", - "postcover": "nyc report --report-dir ./coverage/test --reporter=lcov" + "postcover": "nyc report --report-dir ./coverage/test --reporter=lcov", + "count-async": "node scripts/count-async-functions.mjs", + "check-diff-async": "node scripts/check-diff-async.mjs" } } diff --git a/yarn.lock b/yarn.lock index 71f1438d19..3f3723e891 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2749,6 +2749,13 @@ enabled "2.0.x" kuler "^2.0.0" +"@eslint-community/eslint-utils@^4.1.2", "@eslint-community/eslint-utils@^4.4.0", "@eslint-community/eslint-utils@^4.5.0": + version "4.9.1" + resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz#4e90af67bc51ddee6cdef5284edf572ec376b595" + integrity sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ== + dependencies: + eslint-visitor-keys "^3.4.3" + "@eslint-community/eslint-utils@^4.2.0": version "4.5.1" resolved "https://registry.yarnpkg.com/@eslint-community/eslint-utils/-/eslint-utils-4.5.1.tgz#b0fc7e06d0c94f801537fd4237edc2706d3b8e4c" @@ -2756,6 +2763,11 @@ dependencies: eslint-visitor-keys "^3.4.3" +"@eslint-community/regexpp@^4.11.0": + version "4.12.2" + resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.2.tgz#bccdf615bcf7b6e8db830ec0b8d21c9a25de597b" + integrity sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew== + "@eslint-community/regexpp@^4.12.1": version "4.12.1" resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0" @@ -4948,6 +4960,15 @@ resolved "https://registry.yarnpkg.com/@standard-schema/spec/-/spec-1.0.0.tgz#f193b73dc316c4170f2e82a881da0f550d551b9c" integrity sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA== +"@ts-morph/common@~0.28.1": + version "0.28.1" + resolved "https://registry.yarnpkg.com/@ts-morph/common/-/common-0.28.1.tgz#10ec52182d5c310832b669af7784a34fc3da3ca1" + integrity sha512-W74iWf7ILp1ZKNYXY5qbddNaml7e9Sedv5lvU1V8lftlitkc9Pq1A+jlH23ltDgWYeZFFEqGCD1Ies9hqu3O+g== + dependencies: + minimatch "^10.0.1" + path-browserify "^1.0.1" + tinyglobby "^0.2.14" + "@types/async@^3.2.24": version "3.2.24" resolved "https://registry.yarnpkg.com/@types/async/-/async-3.2.24.tgz#3a96351047575bbcf2340541b2d955a35339608f" @@ -5532,6 +5553,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +balanced-match@^4.0.2: + version "4.0.4" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-4.0.4.tgz#bfb10662feed8196a2c62e7c68e17720c274179a" + integrity sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA== + base-x@3.0.8: version "3.0.8" resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.8.tgz#1e1106c2537f0162e8b52474a557ebb09000018d" @@ -5623,6 +5649,13 @@ brace-expansion@^2.0.1: dependencies: balanced-match "^1.0.0" +brace-expansion@^5.0.2: + version "5.0.3" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-5.0.3.tgz#6a9c6c268f85b53959ec527aeafe0f7300258eef" + integrity sha512-fy6KJm2RawA5RcHkLa1z/ScpBeA762UF9KmZQxwIbDtRJrgLzM10depAiEQ+CXYcoiqW1/m96OAAoke2nE9EeA== + dependencies: + balanced-match "^4.0.2" + braces@~3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" @@ -5901,6 +5934,11 @@ cluster-key-slot@^1.1.0: resolved "https://registry.yarnpkg.com/cluster-key-slot/-/cluster-key-slot-1.1.2.tgz#88ddaa46906e303b5de30d3153b7d9fe0a0c19ac" integrity sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA== +code-block-writer@^13.0.3: + version "13.0.3" + resolved "https://registry.yarnpkg.com/code-block-writer/-/code-block-writer-13.0.3.tgz#90f8a84763a5012da7af61319dd638655ae90b5b" + integrity sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg== + color-convert@^1.9.0, color-convert@^1.9.3: version "1.9.3" resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8" @@ -6433,6 +6471,14 @@ engine.io@~6.6.0: engine.io-parser "~5.2.1" ws "~8.17.1" +enhanced-resolve@^5.17.1: + version "5.19.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.19.0.tgz#6687446a15e969eaa63c2fa2694510e17ae6d97c" + integrity sha512-phv3E1Xl4tQOShqSte26C7Fl84EwUdZsyOuSSk9qtAGyyQs2s3jJzComh+Abf4g187lUUAvH+H26omrqia2aGg== + dependencies: + graceful-fs "^4.2.4" + tapable "^2.3.0" + entities@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" @@ -6638,6 +6684,13 @@ escodegen@1.8.x: optionalDependencies: source-map "~0.2.0" +eslint-compat-utils@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/eslint-compat-utils/-/eslint-compat-utils-0.5.1.tgz#7fc92b776d185a70c4070d03fd26fde3d59652e4" + integrity sha512-3z3vFexKIEnjHE3zCMRo6fn/e44U7T1khUjg+Hp0ZQMCigh28rALD0nPFBcGZuiLC5rLZa2ubQHDRln09JfU2Q== + dependencies: + semver "^7.5.4" + eslint-import-resolver-node@^0.3.9: version "0.3.9" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz#d4eaac52b8a2e7c3cd1903eb00f7e053356118ac" @@ -6654,6 +6707,15 @@ eslint-module-utils@^2.12.0: dependencies: debug "^3.2.7" +eslint-plugin-es-x@^7.8.0: + version "7.8.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-es-x/-/eslint-plugin-es-x-7.8.0.tgz#a207aa08da37a7923f2a9599e6d3eb73f3f92b74" + integrity sha512-7Ds8+wAAoV3T+LAKeu39Y5BzXCrGKrcISfgKEqTS4BDN8SFEDQd0S43jiQ8vIa3wUKD07qitZdfzlenSi8/0qQ== + dependencies: + "@eslint-community/eslint-utils" "^4.1.2" + "@eslint-community/regexpp" "^4.11.0" + eslint-compat-utils "^0.5.1" + eslint-plugin-import@^2.31.0: version "2.31.0" resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz#310ce7e720ca1d9c0bb3f69adfd1c6bdd7d9e0e7" @@ -6688,6 +6750,28 @@ eslint-plugin-mocha@^10.5.0: globals "^13.24.0" rambda "^7.4.0" +eslint-plugin-n@^17.24.0: + version "17.24.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-17.24.0.tgz#b66fa05f7a6c1ba16768f0921b8974147dddd060" + integrity sha512-/gC7/KAYmfNnPNOb3eu8vw+TdVnV0zhdQwexsw6FLXbhzroVj20vRn2qL8lDWDGnAQ2J8DhdfvXxX9EoxvERvw== + dependencies: + "@eslint-community/eslint-utils" "^4.5.0" + enhanced-resolve "^5.17.1" + eslint-plugin-es-x "^7.8.0" + get-tsconfig "^4.8.1" + globals "^15.11.0" + globrex "^0.1.2" + ignore "^5.3.2" + semver "^7.6.3" + ts-declaration-location "^1.0.6" + +eslint-plugin-promise@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-7.2.1.tgz#a0652195700aea40b926dc3c74b38e373377bfb0" + integrity sha512-SWKjd+EuvWkYaS+uN2csvj0KoP43YTu7+phKQ5v+xw6+A0gutVX2yqCeCkC3uLCJFiPfR2dD8Es5L7yUsmvEaA== + dependencies: + "@eslint-community/eslint-utils" "^4.4.0" + eslint-scope@^8.3.0: version "8.3.0" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-8.3.0.tgz#10cd3a918ffdd722f5f3f7b5b83db9b23c87340d" @@ -6956,6 +7040,11 @@ fast-xml-parser@^5.0.7: node-addon-api "^8.3.0" node-gyp "^11.1.0" +fdir@^6.5.0: + version "6.5.0" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.5.0.tgz#ed2ab967a331ade62f18d077dae192684d50d350" + integrity sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg== + fecha@^4.2.0: version "4.2.3" resolved "https://registry.yarnpkg.com/fecha/-/fecha-4.2.3.tgz#4d9ccdbc61e8629b259fdca67e65891448d569fd" @@ -7253,6 +7342,13 @@ get-symbol-description@^1.1.0: es-errors "^1.3.0" get-intrinsic "^1.2.6" +get-tsconfig@^4.8.1: + version "4.13.6" + resolved "https://registry.yarnpkg.com/get-tsconfig/-/get-tsconfig-4.13.6.tgz#2fbfda558a98a691a798f123afd95915badce876" + integrity sha512-shZT/QMiSHc/YBLxxOkMtgSid5HFoauqCE3/exfsEcwg1WkeqjG+V40yBbBrsD+jW2HDXcs28xOfcbm2jI8Ddw== + dependencies: + resolve-pkg-maps "^1.0.0" + getpass@^0.1.1: version "0.1.7" resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" @@ -7326,6 +7422,11 @@ globals@^14.0.0: resolved "https://registry.yarnpkg.com/globals/-/globals-14.0.0.tgz#898d7413c29babcf6bafe56fcadded858ada724e" integrity sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ== +globals@^15.11.0: + version "15.15.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-15.15.0.tgz#7c4761299d41c32b075715a4ce1ede7897ff72a8" + integrity sha512-7ACyT3wmyp3I61S4fG682L0VA2RGD9otkqGJIwNUMF1SWUombIIk+af1unuDYgMm082aHYwD+mzJvv9Iu8dsgg== + globalthis@^1.0.4: version "1.0.4" resolved "https://registry.yarnpkg.com/globalthis/-/globalthis-1.0.4.tgz#7430ed3a975d97bfb59bcce41f5cabbafa651236" @@ -7334,6 +7435,11 @@ globalthis@^1.0.4: define-properties "^1.2.1" gopd "^1.0.1" +globrex@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/globrex/-/globrex-0.1.2.tgz#dd5d9ec826232730cd6793a5e33a9302985e6098" + integrity sha512-uHJgbwAMwNFf5mLst7IWLNg14x1CkeqglJb/K3doi4dw6q2IvAAmM/Y81kevy83wP+Sst+nutFTYOGg3d1lsxg== + google-auth-library@^1.3.1: version "1.6.1" resolved "https://registry.yarnpkg.com/google-auth-library/-/google-auth-library-1.6.1.tgz#9c73d831ad720c0c3048ab89d0ffdec714d07dd2" @@ -7370,7 +7476,7 @@ gopd@^1.0.1, gopd@^1.2.0: resolved "https://registry.yarnpkg.com/gopd/-/gopd-1.2.0.tgz#89f56b8217bdbc8802bd299df6d7f1081d7e51a1" integrity sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg== -graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.6: +graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.2.4, graceful-fs@^4.2.6: version "4.2.11" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.11.tgz#4183e4e8bf08bb6e05bbb2f7d2e0c8f712ca40e3" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -7598,7 +7704,7 @@ ignore-by-default@^1.0.1: resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" integrity sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA== -ignore@^5.2.0: +ignore@^5.2.0, ignore@^5.3.2: version "5.3.2" resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.3.2.tgz#3cd40e729f3643fd87cb04e50bf0eb722bc596f5" integrity sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g== @@ -8914,6 +9020,13 @@ mime@^2.2.0: dependencies: brace-expansion "^1.1.7" +minimatch@^10.0.1: + version "10.2.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-10.2.3.tgz#c0ef582f21071b0123a5bbf275252ebda921fbf6" + integrity sha512-Rwi3pnapEqirPSbWbrZaa6N3nmqq4Xer/2XooiOKyV3q12ML06f7MOuc5DVH8ONZIFhwIYQ3yzPH4nt7iWHaTg== + dependencies: + brace-expansion "^5.0.2" + minimatch@^9.0.4, minimatch@^9.0.5: version "9.0.5" resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-9.0.5.tgz#d74f9dd6b57d83d8e98cfb82133b03978bc929e5" @@ -9560,6 +9673,11 @@ parseurl@^1.3.3, parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +path-browserify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" + integrity sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g== + path-exists@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-4.0.0.tgz#513bdbe2d3b95d7762e8c1137efa195c6c61b5b3" @@ -9625,6 +9743,11 @@ picomatch@^2.0.4, picomatch@^2.2.1: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== +picomatch@^4.0.2, picomatch@^4.0.3: + version "4.0.3" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.3.tgz#796c76136d1eead715db1e7bad785dedd695a042" + integrity sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q== + pidtree@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/pidtree/-/pidtree-0.3.1.tgz#ef09ac2cc0533df1f3250ccf2c4d366b0d12114a" @@ -9997,6 +10120,11 @@ resolve-from@^5.0.0: resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-5.0.0.tgz#c35225843df8f776df21c57557bc087e9dfdfc69" integrity sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw== +resolve-pkg-maps@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz#616b3dc2c57056b5588c31cdf4b3d64db133720f" + integrity sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw== + resolve@1.1.x: version "1.1.7" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" @@ -10133,6 +10261,11 @@ semver@^7.3.5, semver@^7.5.3, semver@^7.5.4: resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== +semver@^7.6.3: + version "7.7.4" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.4.tgz#28464e36060e991fa7a11d0279d2d3f3b57a7e8a" + integrity sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA== + semver@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.1.1.tgz#a3292a373e6f3e0798da0b20641b9a9c5bc47e19" @@ -10716,6 +10849,11 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +tapable@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6" + integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg== + tar@^7.4.3: version "7.4.3" resolved "https://registry.yarnpkg.com/tar/-/tar-7.4.3.tgz#88bbe9286a3fcd900e94592cda7a22b192e80571" @@ -10759,6 +10897,14 @@ tiny-each-async@2.0.3: resolved "https://registry.yarnpkg.com/tiny-each-async/-/tiny-each-async-2.0.3.tgz#8ebbbfd6d6295f1370003fbb37162afe5a0a51d1" integrity sha512-5ROII7nElnAirvFn8g7H7MtpfV1daMcyfTGQwsn/x2VtyV+VPiO5CjReCJtWLvoKTDEDmZocf3cNPraiMnBXLA== +tinyglobby@^0.2.14: + version "0.2.15" + resolved "https://registry.yarnpkg.com/tinyglobby/-/tinyglobby-0.2.15.tgz#e228dd1e638cea993d2fdb4fcd2d4602a79951c2" + integrity sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ== + dependencies: + fdir "^6.5.0" + picomatch "^4.0.3" + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -10815,6 +10961,21 @@ triple-beam@^1.3.0: resolved "https://registry.yarnpkg.com/triple-beam/-/triple-beam-1.4.1.tgz#6fde70271dc6e5d73ca0c3b24e2d92afb7441984" integrity sha512-aZbgViZrg1QNcG+LULa7nhZpJTZSLm/mXnHXnbAbjmN5aSa0y7V+wvv6+4WaBtpISJzThKy+PIPxc1Nq1EJ9mg== +ts-declaration-location@^1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/ts-declaration-location/-/ts-declaration-location-1.0.7.tgz#d4068fe9975828b3b453b3ab112b4711d8267688" + integrity sha512-EDyGAwH1gO0Ausm9gV6T2nUvBgXT5kGoCMJPllOaooZ+4VvJiKBdZE7wK18N1deEowhcUptS+5GXZK8U/fvpwA== + dependencies: + picomatch "^4.0.2" + +ts-morph@^27.0.2: + version "27.0.2" + resolved "https://registry.yarnpkg.com/ts-morph/-/ts-morph-27.0.2.tgz#7b2fcce6822eeca3942fa6c601f159d5920b1422" + integrity sha512-fhUhgeljcrdZ+9DZND1De1029PrE+cMkIP7ooqkLRTrRLTqcki2AstsyJm0vRNbTbVCNJ0idGlbBrfqc7/nA8w== + dependencies: + "@ts-morph/common" "~0.28.1" + code-block-writer "^13.0.3" + tsconfig-paths@^3.15.0: version "3.15.0" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz#5299ec605e55b1abb23ec939ef15edaf483070d4" From 93020af123912cbd9f6e081ee345d1d874b5318f Mon Sep 17 00:00:00 2001 From: DarkIsDude Date: Wed, 25 Feb 2026 16:46:58 +0100 Subject: [PATCH 2/2] =?UTF-8?q?=F0=9F=91=B7=20update=20CI=20to=20add=20new?= =?UTF-8?q?=20check=20on=20async/await=20file?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Issue: CLDSRV-860 --- .github/scripts/check-diff-async.mjs | 142 ++++++++++++++++++++++ .github/scripts/count-async-functions.mjs | 89 ++++++++++++++ .github/workflows/tests.yaml | 18 ++- package.json | 4 +- 4 files changed, 250 insertions(+), 3 deletions(-) create mode 100644 .github/scripts/check-diff-async.mjs create mode 100644 .github/scripts/count-async-functions.mjs diff --git a/.github/scripts/check-diff-async.mjs b/.github/scripts/check-diff-async.mjs new file mode 100644 index 0000000000..b725bc40f7 --- /dev/null +++ b/.github/scripts/check-diff-async.mjs @@ -0,0 +1,142 @@ +/** + * Check that all new/modified functions in the current git diff use async/await. + * Fails with exit code 1 if any additions introduce callback-style functions or .then() chains. + * + * Usage: node scripts/check-diff-async.mjs + * In CI: runs against the current PR diff (files changed vs base branch) + */ +import { execSync } from 'node:child_process'; +import { Project, SyntaxKind } from 'ts-morph'; + +const CALLBACK_PARAM_PATTERN = /^(cb|callback|next|done|err)$/i; + +function getChangedJsFiles() { + const base = process.env.GITHUB_BASE_REF + ? `origin/${process.env.GITHUB_BASE_REF}` + : 'HEAD'; + const output = execSync(`git diff --name-only --diff-filter=ACMR ${base} -- '*.js'`, { + encoding: 'utf8', + }).trim(); + + return output ? output.split('\n').filter(f => f.endsWith('.js')) : []; +} + +/** + * Get added line numbers for a file in the current diff. + */ +function getAddedLineNumbers(filePath) { + const base = process.env.GITHUB_BASE_REF + ? `origin/${process.env.GITHUB_BASE_REF}` + : 'HEAD'; + const diff = execSync(`git diff ${base} -- ${filePath}`, { encoding: 'utf8' }); + const addedLines = new Set(); + let currentLine = 0; + + for (const line of diff.split('\n')) { + const hunkMatch = line.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/); + + if (hunkMatch) { + currentLine = parseInt(hunkMatch[1], 10) - 1; + continue; + } + + if (line.startsWith('+') && !line.startsWith('+++')) { + currentLine++; + addedLines.add(currentLine); + } else if (!line.startsWith('-')) { + currentLine++; + } + } + + return addedLines; +} + +const changedFiles = getChangedJsFiles(); +if (changedFiles.length === 0) { + console.log('No changed JS files to check.'); + process.exit(0); +} + +console.log(`Checking ${changedFiles.length} changed JS file(s) for async/await compliance...\n`); + +const project = new Project({ + compilerOptions: { allowJs: true, noEmit: true }, + skipAddingFilesFromTsConfig: true, +}); + +const filesToCheck = changedFiles.filter(f => + !f.startsWith('tests/') && + !f.startsWith('node_modules/') && + ( + f.startsWith('lib/') || + f.startsWith('bin/') || + !f.includes('/') + ) +); +if (filesToCheck.length === 0) { + console.log('No source JS files in diff (tests and node_modules excluded).'); + process.exit(0); +} + +project.addSourceFilesAtPaths(filesToCheck); + +const violations = []; + +for (const sourceFile of project.getSourceFiles()) { + const filePath = sourceFile.getFilePath().replace(process.cwd() + '/', ''); + const addedLines = getAddedLineNumbers(filePath); + + if (addedLines.size === 0) continue; + + const functions = [ + ...sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration), + ...sourceFile.getDescendantsOfKind(SyntaxKind.FunctionExpression), + ...sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction), + ...sourceFile.getDescendantsOfKind(SyntaxKind.MethodDeclaration), + ]; + + for (const fn of functions) { + if (fn.isAsync()) continue; + + const startLine = fn.getStartLineNumber(); + if (!addedLines.has(startLine)) continue; + + const params = fn.getParameters(); + const lastParam = params[params.length - 1]; + if (lastParam && CALLBACK_PARAM_PATTERN.test(lastParam.getName())) { + violations.push({ + file: filePath, + line: startLine, + type: 'callback', + detail: `function has callback parameter '${lastParam.getName()}'`, + }); + } + } + + const propertyAccesses = sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression); + for (const access of propertyAccesses) { + if (access.getName() !== 'then') continue; + const line = access.getStartLineNumber(); + if (addedLines.has(line)) { + violations.push({ + file: filePath, + line, + type: 'then-chain', + detail: 'use await instead of .then()', + }); + } + } +} + +if (violations.length === 0) { + console.log('✓ All new code in the diff uses async/await.'); + process.exit(0); +} + +console.error(`✗ Found ${violations.length} async/await violation(s) in the diff:\n`); +for (const v of violations) { + console.error(` ${v.file}:${v.line} [${v.type}] ${v.detail}`); +} +console.error('\nNew code must use async/await instead of callbacks or .then() chains.'); +console.error('See the async/await migration guide in CONTRIBUTING.md for help.'); +process.exit(1); diff --git a/.github/scripts/count-async-functions.mjs b/.github/scripts/count-async-functions.mjs new file mode 100644 index 0000000000..300d4a70b9 --- /dev/null +++ b/.github/scripts/count-async-functions.mjs @@ -0,0 +1,89 @@ +/** + * Count async vs callback-style functions across the codebase using ts-morph. + * Used in CI to track async/await migration progress over time. + * + * Usage: node scripts/count-async-functions.mjs + */ +import { Project, SyntaxKind } from 'ts-morph'; + +const project = new Project({ + compilerOptions: { + allowJs: true, + noEmit: true, + }, + skipAddingFilesFromTsConfig: true, +}); + +project.addSourceFilesAtPaths([ + 'lib/**/*.js', + 'index.js', + 'dataserver.js', + 'mdserver.js', + 'managementAgent.js', + 'bin/**/*.js' +]); + +let asyncFunctions = 0; +let totalFunctions = 0; +let callbackFunctions = 0; +let thenChains = 0; + +const CALLBACK_PARAM_PATTERN = /^(cb|callback|next|done|err)$/i; + +for (const sourceFile of project.getSourceFiles()) { + const functions = [ + ...sourceFile.getDescendantsOfKind(SyntaxKind.FunctionDeclaration), + ...sourceFile.getDescendantsOfKind(SyntaxKind.FunctionExpression), + ...sourceFile.getDescendantsOfKind(SyntaxKind.ArrowFunction), + ...sourceFile.getDescendantsOfKind(SyntaxKind.MethodDeclaration), + ]; + + for (const fn of functions) { + totalFunctions++; + + if (fn.isAsync()) { + asyncFunctions++; + continue; + } + + const params = fn.getParameters(); + const lastParam = params[params.length - 1]; + if (lastParam && CALLBACK_PARAM_PATTERN.test(lastParam.getName())) { + callbackFunctions++; + } + } + + const propertyAccesses = sourceFile.getDescendantsOfKind(SyntaxKind.PropertyAccessExpression); + for (const access of propertyAccesses) { + if (access.getName() === 'then') { + thenChains++; + } + } +} + +const migrationPercent = totalFunctions > 0 + ? ((asyncFunctions / totalFunctions) * 100).toFixed(1) + : '0.0'; + +console.log('=== Async/Await Migration Progress ==='); +console.log(`Total functions: ${totalFunctions}`); +console.log(`Async functions: ${asyncFunctions} (${migrationPercent}%)`); +console.log(`Callback functions: ${callbackFunctions}`); +console.log(`Remaining .then(): ${thenChains}`); +console.log(''); +console.log(`Migration: ${asyncFunctions}/${totalFunctions} functions (${migrationPercent}%)`); + +if (process.env.GITHUB_STEP_SUMMARY) { + const { writeFileSync, appendFileSync } = await import('node:fs'); + appendFileSync(process.env.GITHUB_STEP_SUMMARY, [ + '## Async/Await Migration Progress', + '', + `| Metric | Count |`, + `|--------|-------|`, + `| Total functions | ${totalFunctions} |`, + `| Async functions | ${asyncFunctions} (${migrationPercent}%) |`, + `| Callback-style functions | ${callbackFunctions} |`, + `| Remaining \`.then()\` chains | ${thenChains} |`, + '', + ].join('\n')); +} diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index d2efe78c63..0ab4585952 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -96,13 +96,29 @@ jobs: - name: Install python deps run: pip install flake8 - name: Lint Javascript - run: yarn run --silent lint -- --max-warnings 0 + run: yarn run --silent lint - name: Lint Markdown run: yarn run --silent lint_md - name: Lint python run: flake8 $(git ls-files "*.py") - name: Lint Yaml run: yamllint -c yamllint.yml $(git ls-files "*.yml") + - name: Check async/await compliance in diff + run: yarn run check-diff-async + + async-migration-report: + runs-on: ubuntu-24.04 + steps: + - name: Checkout + uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '22' + cache: yarn + - name: install dependencies + run: yarn install --frozen-lockfile --network-concurrency 1 + - name: Count async/await migration progress + run: yarn run count-async unit-tests: runs-on: ubuntu-24.04 diff --git a/package.json b/package.json index 037697c3da..59ebdd6c7d 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,7 @@ "multiple_backend_test": "CI=true S3BACKEND=mem S3METADATA=mem S3DATA=multiple mocha --reporter mocha-multi-reporters --reporter-options configFile=$INIT_CWD/tests/reporter-config.json -t 20000 --recursive tests/multipleBackend --exit", "cover": "nyc --clean --silent yarn run", "postcover": "nyc report --report-dir ./coverage/test --reporter=lcov", - "count-async": "node scripts/count-async-functions.mjs", - "check-diff-async": "node scripts/check-diff-async.mjs" + "count-async": "node .github/scripts/count-async-functions.mjs", + "check-diff-async": "node .github/scripts/check-diff-async.mjs" } }