diff --git a/package-lock.json b/package-lock.json index c79dba128..4adc863d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -22,7 +22,6 @@ "morgan": "^1.9.1", "multistream": "^2.1.1", "mysql2": "^3.10.1", - "rimraf": "^3.0.2", "sequelize": "^6.31.0", "stoppable": "^1.1.0", "tedious": "^16.7.0", @@ -58,7 +57,6 @@ "@types/morgan": "^1.7.35", "@types/multistream": "^2.1.1", "@types/node": "^14.14.24", - "@types/rimraf": "^3.0.0", "@types/stoppable": "^1.1.1", "@types/uri-templates": "^0.1.29", "@types/uuid": "^3.4.4", @@ -1357,16 +1355,6 @@ "@types/node": "*" } }, - "node_modules/@types/glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", - "dev": true, - "dependencies": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, "node_modules/@types/glob-to-regexp": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@types/glob-to-regexp/-/glob-to-regexp-0.4.3.tgz", @@ -1409,12 +1397,6 @@ "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==", "dev": true }, - "node_modules/@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, "node_modules/@types/mocha": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", @@ -1463,16 +1445,6 @@ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", "dev": true }, - "node_modules/@types/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==", - "dev": true, - "dependencies": { - "@types/glob": "*", - "@types/node": "*" - } - }, "node_modules/@types/semver": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", @@ -3144,7 +3116,8 @@ "node_modules/balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "node_modules/base64-js": { "version": "1.5.1", @@ -3324,6 +3297,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "dependencies": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -3728,7 +3702,8 @@ "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "node_modules/content-disposition": { "version": "0.5.4", @@ -5460,7 +5435,8 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "node_modules/fsevents": { "version": "2.3.3", @@ -5590,6 +5566,7 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -6188,6 +6165,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -7430,6 +7408,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "dependencies": { "brace-expansion": "^1.1.7" }, @@ -7908,6 +7887,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "dependencies": { "wrappy": "1" } @@ -8073,6 +8053,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, "engines": { "node": ">=0.10.0" } @@ -8934,6 +8915,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "dependencies": { "glob": "^7.1.3" }, @@ -10495,7 +10477,8 @@ "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "node_modules/xml2js": { "version": "0.6.2", @@ -11650,16 +11633,6 @@ "@types/node": "*" } }, - "@types/glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-w+LsMxKyYQm347Otw+IfBXOv9UWVjpHpCDdbBMt8Kz/xbvCYNjP+0qPh91Km3iKfSRLBB0P7fAMf0KHrPu+MyA==", - "dev": true, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, "@types/glob-to-regexp": { "version": "0.4.3", "resolved": "https://registry.npmjs.org/@types/glob-to-regexp/-/glob-to-regexp-0.4.3.tgz", @@ -11702,12 +11675,6 @@ "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==", "dev": true }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, "@types/mocha": { "version": "9.1.1", "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-9.1.1.tgz", @@ -11756,16 +11723,6 @@ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", "dev": true }, - "@types/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-F3OznnSLAUxFrCEu/L5PY8+ny8DtcFRjx7fZZ9bycvXRi3KPTRS9HOitGZwvPg0juRhXFWIeKX58cnX5YqLohQ==", - "dev": true, - "requires": { - "@types/glob": "*", - "@types/node": "*" - } - }, "@types/semver": { "version": "7.5.0", "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz", @@ -12027,15 +11984,13 @@ "acorn-import-assertions": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "requires": {} + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==" }, "acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "8.2.0", @@ -13202,7 +13157,8 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true }, "base64-js": { "version": "1.5.1", @@ -13325,6 +13281,7 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -13632,7 +13589,8 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true }, "content-disposition": { "version": "0.5.4", @@ -13937,8 +13895,7 @@ "diagnostic-channel-publishers": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/diagnostic-channel-publishers/-/diagnostic-channel-publishers-1.0.8.tgz", - "integrity": "sha512-HmSm9hXxSPxA9BaLGY98QU1zsdjeCk113KjAYGPCen1ZP6mhVaTPzHd6UYv5r21DnWANi+f+NyPOHruGT9jpqQ==", - "requires": {} + "integrity": "sha512-HmSm9hXxSPxA9BaLGY98QU1zsdjeCk113KjAYGPCen1ZP6mhVaTPzHd6UYv5r21DnWANi+f+NyPOHruGT9jpqQ==" }, "diff": { "version": "5.2.0", @@ -14900,7 +14857,8 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "fsevents": { "version": "2.3.3", @@ -14990,6 +14948,7 @@ "version": "7.1.4", "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -15404,6 +15363,7 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -16328,6 +16288,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, "requires": { "brace-expansion": "^1.1.7" } @@ -16687,6 +16648,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -16811,7 +16773,8 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-key": { "version": "4.0.0", @@ -17447,6 +17410,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, "requires": { "glob": "^7.1.3" } @@ -18593,7 +18557,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "xml2js": { "version": "0.6.2", diff --git a/package.json b/package.json index 6df18cfcb..df8467721 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,6 @@ "morgan": "^1.9.1", "multistream": "^2.1.1", "mysql2": "^3.10.1", - "rimraf": "^3.0.2", "sequelize": "^6.31.0", "stoppable": "^1.1.0", "tedious": "^16.7.0", @@ -63,7 +62,6 @@ "@types/morgan": "^1.7.35", "@types/multistream": "^2.1.1", "@types/node": "^14.14.24", - "@types/rimraf": "^3.0.0", "@types/stoppable": "^1.1.1", "@types/uri-templates": "^0.1.29", "@types/uuid": "^3.4.4", @@ -323,8 +321,8 @@ "test:table:in-memory": "npm run lint && cross-env AZURITE_TEST_INMEMORYPERSISTENCE=1 NODE_TLS_REJECT_UNAUTHORIZED=0 mocha --require ts-node/register --no-timeouts --recursive --exit tests/table/**/*.test.ts", "test:exe": "npm run lint && cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 mocha --require ts-node/register --no-timeouts tests/exe.test.ts --exit", "test:linux": "npm run lint && cross-env NODE_TLS_REJECT_UNAUTHORIZED=0 mocha --require ts-node/register --no-timeouts tests/linuxbinary.test.ts --exit", - "clean": "rimraf dist typings *.log coverage __testspersistence__ temp __testsstorage__ .nyc_output debug.log *.vsix *.tgz", - "clean:deep": "npm run clean && rimraf debug.log __*", + "clean": "node scripts/clean.js", + "clean:deep": "node scripts/clean.js --deep", "validate:npmpack:win": "npm install --legacy-peer-deps && npm run build && npm pack && cross-var npm install -g azurite-$npm_package_version.tgz && azurite -v && azurite-blob -v && azurite-queue -v && azurite-table -v", "validate:npmpack:linux_mac": "npm install --legacy-peer-deps && npm run build && npm pack && cross-var sudo npm install -g azurite-$npm_package_version.tgz && azurite -v && azurite-blob -v && azurite-queue -v && azurite-table -v", "db:migrate:blob:metadata": "sequelize db:migrate --config migrations/blob/metadata/config/config.json --migrations-path migrations/blob/metadata/migrations", diff --git a/scripts/clean.js b/scripts/clean.js new file mode 100644 index 000000000..4805d4940 --- /dev/null +++ b/scripts/clean.js @@ -0,0 +1,103 @@ +/** + * Cross-platform clean script that replaces the rimraf CLI. + * Removes build artifacts, logs, and temporary directories. + * + * Usage: + * node scripts/clean.js (standard clean) + * node scripts/clean.js --deep (deep clean, also removes debug.log and __* dirs) + */ + +const fs = require("fs"); +const path = require("path"); + +const rootDir = path.resolve(__dirname, ".."); + +/** + * Remove a file or directory at the given absolute path. + * Silently ignores ENOENT (already missing). + */ +function rm(target) { + try { + fs.rmSync(target, { recursive: true, force: true }); + } catch (err) { + if (err.code !== "ENOENT") { + console.error(`Warning: could not remove ${target}: ${err.message}`); + } + } +} + +/** + * Remove all entries in rootDir matching a simple glob pattern (e.g. "*.log"). + * Only supports single-level "*.ext" patterns in the project root. + */ +function rmGlob(pattern) { + // Extract the extension from a "*.ext" pattern + const match = pattern.match(/^\*(\..+)$/); + if (!match) { + throw new Error(`Unsupported glob pattern: ${pattern}`); + } + const ext = match[1]; + let entries; + try { + entries = fs.readdirSync(rootDir); + } catch { + return; + } + for (const entry of entries) { + if (entry.endsWith(ext)) { + rm(path.join(rootDir, entry)); + } + } +} + +/** + * Remove all entries in rootDir matching a prefix pattern (e.g. "__*"). + */ +function rmPrefix(pattern) { + const match = pattern.match(/^(.+)\*$/); + if (!match) { + throw new Error(`Unsupported prefix pattern: ${pattern}`); + } + const prefix = match[1]; + let entries; + try { + entries = fs.readdirSync(rootDir); + } catch { + return; + } + for (const entry of entries) { + if (entry.startsWith(prefix)) { + rm(path.join(rootDir, entry)); + } + } +} + +// Standard clean targets (matches the old "clean" npm script): +// rimraf dist typings *.log coverage __testspersistence__ temp __testsstorage__ .nyc_output debug.log *.vsix *.tgz +const staticTargets = [ + "dist", + "typings", + "coverage", + "__testspersistence__", + "temp", + "__testsstorage__", + ".nyc_output", + "debug.log" +]; + +const globTargets = ["*.log", "*.vsix", "*.tgz"]; + +// Remove static targets +for (const target of staticTargets) { + rm(path.join(rootDir, target)); +} + +// Remove glob targets +for (const pattern of globTargets) { + rmGlob(pattern); +} + +// Deep clean: also remove debug.log (already covered above) and all __* entries +if (process.argv.includes("--deep")) { + rmPrefix("__*"); +} diff --git a/src/common/utils/utils.ts b/src/common/utils/utils.ts index 3debf4f56..79189c650 100644 --- a/src/common/utils/utils.ts +++ b/src/common/utils/utils.ts @@ -1,7 +1,6 @@ import { createHash, createHmac } from "crypto"; -import rimraf = require("rimraf"); +import { promises as fsPromises } from "fs"; import { parse } from "url"; -import { promisify } from "util"; import StorageErrorFactory from "../../blob/errors/StorageErrorFactory"; import { VALID_CSHARP_IDENTIFIER_REGEX } from "./constants"; @@ -9,7 +8,13 @@ import { VALID_CSHARP_IDENTIFIER_REGEX } from "./constants"; // tslint:disable-next-line:no-var-requires export const lfsa = require("lokijs/src/loki-fs-structured-adapter.js"); -export const rimrafAsync = promisify(rimraf); +export async function rimrafAsync(path: string): Promise { + await fsPromises.rm(path, { + recursive: true, + force: true, + maxRetries: process.platform === "win32" ? 10 : 0 + }); +} export function minDate(date1: Date, date2: Date): Date { return date1 > date2 ? date2 : date1; diff --git a/tests/testutils.ts b/tests/testutils.ts index 86c214622..e0fc1d32e 100644 --- a/tests/testutils.ts +++ b/tests/testutils.ts @@ -1,9 +1,8 @@ import { StorageServiceClient } from "azure-storage"; import { randomBytes } from "crypto"; -import { createWriteStream, readFileSync } from "fs"; +import { createWriteStream, readFileSync, promises as fsPromises } from "fs"; import { sign } from "jsonwebtoken"; import { join } from "path"; -import rimraf from "rimraf"; import { URL } from "url"; export const EMULATOR_ACCOUNT_NAME = "devstoreaccount1"; @@ -49,16 +48,10 @@ export function padStart( } export async function rmRecursive(path: string): Promise { - return new Promise((resolve, reject) => { - rimraf(path, (err) => { - if (err) { - resolve(); - // TODO: Handle delete errors - // reject(err); - } else { - resolve(); - } - }); + await fsPromises.rm(path, { + recursive: true, + force: true, + maxRetries: process.platform === "win32" ? 10 : 0 }); }