Make glob tool support abortSignal (#988)

This commit is contained in:
Tommaso Sciortino 2025-06-12 13:27:40 -07:00 committed by GitHub
parent 32da693b91
commit f8863f4d00
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 80 additions and 80 deletions

59
package-lock.json generated
View File

@ -1022,7 +1022,6 @@
"version": "8.0.2",
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
"integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
"dev": true,
"license": "ISC",
"dependencies": {
"string-width": "^5.1.2",
@ -1207,6 +1206,7 @@
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "2.0.5",
@ -1220,6 +1220,7 @@
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 8"
@ -1229,6 +1230,7 @@
"version": "1.2.8",
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.scandir": "2.1.5",
@ -1708,7 +1710,6 @@
"version": "0.11.0",
"resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
"integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
"dev": true,
"license": "MIT",
"optional": true,
"engines": {
@ -2187,6 +2188,16 @@
"dev": true,
"license": "MIT"
},
"node_modules/@types/glob": {
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-8.1.0.tgz",
"integrity": "sha512-IO+MJPVhoqz+28h1qLAcBEH2+xHMK6MTyHJc7MTnnYb6wsoLR29POVGJ7LycmVXIqyy/4/2ShP5sUwTXuOwb/w==",
"license": "MIT",
"dependencies": {
"@types/minimatch": "^5.1.2",
"@types/node": "*"
}
},
"node_modules/@types/gradient-string": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/@types/gradient-string/-/gradient-string-1.1.6.tgz",
@ -2240,7 +2251,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz",
"integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/node": {
@ -3116,7 +3126,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
"dev": true,
"license": "MIT"
},
"node_modules/base64-js": {
@ -3183,6 +3192,7 @@
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
"integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
"dev": true,
"license": "MIT",
"dependencies": {
"fill-range": "^7.1.1"
@ -4025,7 +4035,6 @@
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
"integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
"dev": true,
"license": "MIT"
},
"node_modules/ecdsa-sig-formatter": {
@ -4047,7 +4056,6 @@
"version": "9.2.2",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
"integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
"dev": true,
"license": "MIT"
},
"node_modules/encodeurl": {
@ -4865,6 +4873,7 @@
"version": "3.3.3",
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
"integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@nodelib/fs.stat": "^2.0.2",
@ -4881,6 +4890,7 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
"dev": true,
"license": "ISC",
"dependencies": {
"is-glob": "^4.0.1"
@ -4906,6 +4916,7 @@
"version": "1.19.1",
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz",
"integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==",
"dev": true,
"license": "ISC",
"dependencies": {
"reusify": "^1.0.4"
@ -4943,6 +4954,7 @@
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
"integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
"dev": true,
"license": "MIT",
"dependencies": {
"to-regex-range": "^5.0.1"
@ -5038,7 +5050,6 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
"integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
"dev": true,
"license": "ISC",
"dependencies": {
"cross-spawn": "^7.0.6",
@ -5235,7 +5246,6 @@
"version": "10.4.5",
"resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
"integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
"dev": true,
"license": "ISC",
"dependencies": {
"foreground-child": "^3.1.0",
@ -5269,7 +5279,6 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
"integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
"dev": true,
"license": "MIT",
"dependencies": {
"balanced-match": "^1.0.0"
@ -5279,7 +5288,6 @@
"version": "9.0.5",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
"integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
"dev": true,
"license": "ISC",
"dependencies": {
"brace-expansion": "^2.0.1"
@ -6165,6 +6173,7 @@
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
"integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.10.0"
@ -6221,6 +6230,7 @@
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
"integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-extglob": "^2.1.1"
@ -6292,6 +6302,7 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=0.12.0"
@ -6600,7 +6611,6 @@
"version": "3.4.3",
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
"integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"@isaacs/cliui": "^8.0.2"
@ -7023,6 +7033,7 @@
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 8"
@ -7032,6 +7043,7 @@
"version": "4.0.8",
"resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz",
"integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==",
"dev": true,
"license": "MIT",
"dependencies": {
"braces": "^3.0.3",
@ -7098,7 +7110,6 @@
"version": "7.1.2",
"resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
"integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=16 || 14 >=14.17"
@ -7490,7 +7501,6 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
"integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
"dev": true,
"license": "BlueOak-1.0.0"
},
"node_modules/parent-module": {
@ -7583,7 +7593,6 @@
"version": "1.11.1",
"resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
"integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
"dev": true,
"license": "BlueOak-1.0.0",
"dependencies": {
"lru-cache": "^10.2.0",
@ -7632,6 +7641,7 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8.6"
@ -7825,6 +7835,7 @@
"version": "1.2.3",
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
"dev": true,
"funding": [
{
"type": "github",
@ -8094,6 +8105,7 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz",
"integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==",
"dev": true,
"license": "MIT",
"engines": {
"iojs": ">=1.0.0",
@ -8179,6 +8191,7 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
"dev": true,
"funding": [
{
"type": "github",
@ -8546,7 +8559,6 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
"integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
"dev": true,
"license": "ISC",
"engines": {
"node": ">=14"
@ -8717,7 +8729,6 @@
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
"integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
"dev": true,
"license": "MIT",
"dependencies": {
"eastasianwidth": "^0.2.0",
@ -8736,7 +8747,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@ -8751,14 +8761,12 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@ -8768,7 +8776,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@ -8895,7 +8902,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@ -9152,6 +9158,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"is-number": "^7.0.0"
@ -10474,7 +10481,6 @@
"version": "8.1.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
"integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^6.1.0",
@ -10493,7 +10499,6 @@
"version": "7.0.0",
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
"integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.0.0",
@ -10511,14 +10516,12 @@
"version": "8.0.0",
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
"integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
"dev": true,
"license": "MIT"
},
"node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@ -10528,7 +10531,6 @@
"version": "4.2.3",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
"integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
"dev": true,
"license": "MIT",
"dependencies": {
"emoji-regex": "^8.0.0",
@ -10543,7 +10545,6 @@
"version": "6.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
"integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-regex": "^5.0.1"
@ -10556,7 +10557,6 @@
"version": "6.2.1",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
"integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
@ -10806,9 +10806,10 @@
"@opentelemetry/exporter-trace-otlp-grpc": "^0.52.0",
"@opentelemetry/instrumentation-http": "^0.52.0",
"@opentelemetry/sdk-node": "^0.52.0",
"@types/glob": "^8.1.0",
"diff": "^7.0.0",
"dotenv": "^16.4.7",
"fast-glob": "^3.3.3",
"glob": "^10.4.5",
"google-auth-library": "^9.11.0",
"ignore": "^7.0.0",
"open": "^10.1.2",

View File

@ -29,9 +29,10 @@
"@opentelemetry/exporter-trace-otlp-grpc": "^0.52.0",
"@opentelemetry/instrumentation-http": "^0.52.0",
"@opentelemetry/sdk-node": "^0.52.0",
"@types/glob": "^8.1.0",
"diff": "^7.0.0",
"dotenv": "^16.4.7",
"fast-glob": "^3.3.3",
"glob": "^10.4.5",
"google-auth-library": "^9.11.0",
"ignore": "^7.0.0",
"open": "^10.1.2",

View File

@ -4,17 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/
import {
GlobTool,
GlobToolParams,
sortFileEntries,
GlobFileEntry,
} from './glob.js';
import { GlobTool, GlobToolParams, GlobPath, sortFileEntries } from './glob.js';
import { partListUnionToString } from '../core/geminiRequest.js';
// import { ToolResult } from './tools.js'; // ToolResult is implicitly used by execute
import path from 'path';
import fs from 'fs/promises';
import { Stats } from 'fs';
import os from 'os';
import { describe, it, expect, beforeEach, afterEach } from 'vitest'; // Removed vi
import { FileDiscoveryService } from '../services/fileDiscoveryService.js';
@ -274,9 +267,9 @@ describe('sortFileEntries', () => {
const nowTimestamp = new Date('2024-01-15T12:00:00.000Z').getTime();
const oneDayInMs = 24 * 60 * 60 * 1000;
const createFileEntry = (path: string, mtimeDate: Date): GlobFileEntry => ({
path,
stats: { mtime: mtimeDate } as Stats,
const createFileEntry = (fullpath: string, mtimeDate: Date): GlobPath => ({
fullpath: () => fullpath,
mtimeMs: mtimeDate.getTime(),
});
it('should sort a mix of recent and older files correctly', () => {
@ -289,7 +282,7 @@ describe('sortFileEntries', () => {
nowTimestamp - (oneDayInMs + 2 * 60 * 60 * 1000),
); // 26 hours ago
const entries: GlobFileEntry[] = [
const entries: GlobPath[] = [
createFileEntry('older_zebra.txt', olderTime2),
createFileEntry('recent_alpha.txt', recentTime1),
createFileEntry('older_apple.txt', olderTime1),
@ -298,7 +291,7 @@ describe('sortFileEntries', () => {
];
const sorted = sortFileEntries(entries, nowTimestamp, oneDayInMs);
const sortedPaths = sorted.map((e) => e.path);
const sortedPaths = sorted.map((e) => e.fullpath());
expect(sortedPaths).toEqual([
'recent_alpha.txt', // Recent, newest
@ -314,24 +307,28 @@ describe('sortFileEntries', () => {
const recentTime2 = new Date(nowTimestamp - 2000);
const recentTime3 = new Date(nowTimestamp - 3000); // Oldest recent
const entries: GlobFileEntry[] = [
const entries: GlobPath[] = [
createFileEntry('c.txt', recentTime2),
createFileEntry('a.txt', recentTime3),
createFileEntry('b.txt', recentTime1),
];
const sorted = sortFileEntries(entries, nowTimestamp, oneDayInMs);
expect(sorted.map((e) => e.path)).toEqual(['b.txt', 'c.txt', 'a.txt']);
expect(sorted.map((e) => e.fullpath())).toEqual([
'b.txt',
'c.txt',
'a.txt',
]);
});
it('should sort only older files alphabetically by path', () => {
const olderTime = new Date(nowTimestamp - 2 * oneDayInMs); // All equally old
const entries: GlobFileEntry[] = [
const entries: GlobPath[] = [
createFileEntry('zebra.txt', olderTime),
createFileEntry('apple.txt', olderTime),
createFileEntry('banana.txt', olderTime),
];
const sorted = sortFileEntries(entries, nowTimestamp, oneDayInMs);
expect(sorted.map((e) => e.path)).toEqual([
expect(sorted.map((e) => e.fullpath())).toEqual([
'apple.txt',
'banana.txt',
'zebra.txt',
@ -339,30 +336,30 @@ describe('sortFileEntries', () => {
});
it('should handle an empty array', () => {
const entries: GlobFileEntry[] = [];
const entries: GlobPath[] = [];
const sorted = sortFileEntries(entries, nowTimestamp, oneDayInMs);
expect(sorted).toEqual([]);
});
it('should correctly sort files when mtimes are identical for older files', () => {
const olderTime = new Date(nowTimestamp - 2 * oneDayInMs);
const entries: GlobFileEntry[] = [
const entries: GlobPath[] = [
createFileEntry('b.txt', olderTime),
createFileEntry('a.txt', olderTime),
];
const sorted = sortFileEntries(entries, nowTimestamp, oneDayInMs);
expect(sorted.map((e) => e.path)).toEqual(['a.txt', 'b.txt']);
expect(sorted.map((e) => e.fullpath())).toEqual(['a.txt', 'b.txt']);
});
it('should correctly sort files when mtimes are identical for recent files (maintaining mtime sort)', () => {
const recentTime = new Date(nowTimestamp - 1000);
const entries: GlobFileEntry[] = [
const entries: GlobPath[] = [
createFileEntry('b.txt', recentTime),
createFileEntry('a.txt', recentTime),
];
const sorted = sortFileEntries(entries, nowTimestamp, oneDayInMs);
expect(sorted.map((e) => e.path)).toContain('a.txt');
expect(sorted.map((e) => e.path)).toContain('b.txt');
expect(sorted.map((e) => e.fullpath())).toContain('a.txt');
expect(sorted.map((e) => e.fullpath())).toContain('b.txt');
expect(sorted.length).toBe(2);
});
@ -371,12 +368,12 @@ describe('sortFileEntries', () => {
const justUnderThreshold = new Date(nowTimestamp - (1000 - 1)); // Barely recent
const customThresholdMs = 1000; // 1 second
const entries: GlobFileEntry[] = [
const entries: GlobPath[] = [
createFileEntry('older_file.txt', justOverThreshold),
createFileEntry('recent_file.txt', justUnderThreshold),
];
const sorted = sortFileEntries(entries, nowTimestamp, customThresholdMs);
expect(sorted.map((e) => e.path)).toEqual([
expect(sorted.map((e) => e.fullpath())).toEqual([
'recent_file.txt',
'older_file.txt',
]);

View File

@ -6,16 +6,16 @@
import fs from 'fs';
import path from 'path';
import fg from 'fast-glob';
import { glob } from 'glob';
import { SchemaValidator } from '../utils/schemaValidator.js';
import { BaseTool, ToolResult } from './tools.js';
import { shortenPath, makeRelative } from '../utils/paths.js';
import { Config } from '../config/config.js';
// Type definition for file entries returned by fast-glob with stats: true
export interface GlobFileEntry {
path: string;
stats?: fs.Stats;
// Subset of 'Path' interface provided by 'glob' that we can implement for testing
export interface GlobPath {
fullpath(): string;
mtimeMs?: number;
}
/**
@ -24,14 +24,14 @@ export interface GlobFileEntry {
* Older files are listed after recent ones, sorted alphabetically by path.
*/
export function sortFileEntries(
entries: GlobFileEntry[],
entries: GlobPath[],
nowTimestamp: number,
recencyThresholdMs: number,
): GlobFileEntry[] {
): GlobPath[] {
const sortedEntries = [...entries];
sortedEntries.sort((a, b) => {
const mtimeA = a.stats?.mtime?.getTime() ?? 0;
const mtimeB = b.stats?.mtime?.getTime() ?? 0;
const mtimeA = a.mtimeMs ?? 0;
const mtimeB = b.mtimeMs ?? 0;
const aIsRecent = nowTimestamp - mtimeA < recencyThresholdMs;
const bIsRecent = nowTimestamp - mtimeB < recencyThresholdMs;
@ -42,7 +42,7 @@ export function sortFileEntries(
} else if (bIsRecent) {
return 1;
} else {
return a.path.localeCompare(b.path);
return a.fullpath().localeCompare(b.fullpath());
}
});
return sortedEntries;
@ -201,7 +201,7 @@ export class GlobTool extends BaseTool<GlobToolParams, ToolResult> {
*/
async execute(
params: GlobToolParams,
_signal: AbortSignal,
signal: AbortSignal,
): Promise<ToolResult> {
const validationError = this.validateToolParams(params);
if (validationError) {
@ -223,26 +223,25 @@ export class GlobTool extends BaseTool<GlobToolParams, ToolResult> {
this.config.getFileFilteringRespectGitIgnore();
const fileDiscovery = await this.config.getFileService();
const entries = await fg(params.pattern, {
const entries = (await glob(params.pattern, {
cwd: searchDirAbsolute,
absolute: true,
onlyFiles: true,
stats: true,
withFileTypes: true,
nodir: true,
stat: true,
nocase: !params.case_sensitive,
dot: true,
caseSensitiveMatch: params.case_sensitive ?? false,
ignore: ['**/node_modules/**', '**/.git/**'],
followSymbolicLinks: false,
suppressErrors: true,
});
follow: false,
signal,
})) as GlobPath[];
// Apply git-aware filtering if enabled and in git repository
let filteredEntries = entries;
let gitIgnoredCount = 0;
if (respectGitIgnore && fileDiscovery.isGitRepository()) {
const allPaths = entries.map((entry) => entry.path);
const relativePaths = allPaths.map((p) =>
path.relative(this.rootDirectory, p),
const relativePaths = entries.map((p) =>
path.relative(this.rootDirectory, p.fullpath()),
);
const filteredRelativePaths = fileDiscovery.filterFiles(relativePaths, {
respectGitIgnore,
@ -252,7 +251,7 @@ export class GlobTool extends BaseTool<GlobToolParams, ToolResult> {
);
filteredEntries = entries.filter((entry) =>
filteredAbsolutePaths.has(entry.path),
filteredAbsolutePaths.has(entry.fullpath()),
);
gitIgnoredCount = entries.length - filteredEntries.length;
}
@ -274,12 +273,14 @@ export class GlobTool extends BaseTool<GlobToolParams, ToolResult> {
// Sort the filtered entries using the new helper function
const sortedEntries = sortFileEntries(
filteredEntries as GlobFileEntry[], // Cast because fast-glob's Entry type is generic
filteredEntries,
nowTimestamp,
oneDayInMs,
);
const sortedAbsolutePaths = sortedEntries.map((entry) => entry.path);
const sortedAbsolutePaths = sortedEntries.map((entry) =>
entry.fullpath(),
);
const fileListDescription = sortedAbsolutePaths.join('\n');
const fileCount = sortedAbsolutePaths.length;