diff --git a/.github/workflows/spec-gen-sdk-runner-test.yaml b/.github/workflows/spec-gen-sdk-runner-test.yaml new file mode 100644 index 000000000000..a53066f95627 --- /dev/null +++ b/.github/workflows/spec-gen-sdk-runner-test.yaml @@ -0,0 +1,32 @@ +name: spec-gen-sdk-runner - Test + +on: + push: + branches: + - main + - typespec-next + pull_request: + paths: + - package-lock.json + - package.json + - tsconfig.json + - .github/workflows/_reusable-eng-tools-test.yaml + - .github/workflows/spec-gen-sdk-runner-test.yaml + - eng/tools/package.json + - eng/tools/tsconfig.json + - eng/tools/spec-gen-sdk-runner/** + workflow_dispatch: + +permissions: + contents: read + +jobs: + specGenSdkRunner: + name: spec-gen-sdk-runner + uses: ./.github/workflows/_reusable-eng-tools-test.yaml + with: + package: spec-gen-sdk-runner + lint: true + sparse-checkout-paths: | + specification/common-types + specification/contosowidgetmanager diff --git a/eng/tools/spec-gen-sdk-runner/package.json b/eng/tools/spec-gen-sdk-runner/package.json index 15d3db303a87..371039308d06 100644 --- a/eng/tools/spec-gen-sdk-runner/package.json +++ b/eng/tools/spec-gen-sdk-runner/package.json @@ -15,12 +15,12 @@ "test:ci": "vitest run --coverage --reporter=verbose" }, "engines": { - "node": ">= 18.0.0" + "node": ">=20.0.0" }, "devDependencies": { "@types/node": "^18.19.31", - "@vitest/coverage-c8": "^0.33.0", + "@vitest/coverage-v8": "^3.0.5", "typescript": "~5.6.2", - "vitest": "^3.0.7" + "vitest": "^3.0.5" } } diff --git a/eng/tools/spec-gen-sdk-runner/src/utils.ts b/eng/tools/spec-gen-sdk-runner/src/utils.ts index 839c286b2774..d486fb9e78e0 100644 --- a/eng/tools/spec-gen-sdk-runner/src/utils.ts +++ b/eng/tools/spec-gen-sdk-runner/src/utils.ts @@ -60,7 +60,7 @@ export function getArgumentValue(args: string[], flag: string, defaultValue: str * Get the relative path from the specification folder */ export function getRelativePathFromSpecification(absolutePath: string): string { - const specificationIndex = absolutePath.indexOf("specification/"); + const specificationIndex = absolutePath.indexOf(path.normalize("specification/")); if (specificationIndex !== -1) { return absolutePath.slice(Math.max(0, specificationIndex)); } diff --git a/eng/tools/spec-gen-sdk-runner/test/utils/createCombinedSpecs.test.ts b/eng/tools/spec-gen-sdk-runner/test/utils/createCombinedSpecs.test.ts index 7496d1a864e8..591a997b5109 100644 --- a/eng/tools/spec-gen-sdk-runner/test/utils/createCombinedSpecs.test.ts +++ b/eng/tools/spec-gen-sdk-runner/test/utils/createCombinedSpecs.test.ts @@ -1,5 +1,6 @@ import { describe, test, expect } from "vitest"; import { createCombinedSpecs, type SpecResults } from "../../src/utils.js"; +import path from "node:path"; describe("createCombinedSpecs", () => { test("combines specs from readme and typespec paths", () => { @@ -26,9 +27,9 @@ describe("createCombinedSpecs", () => { expect(result[0].specs).toContain("api.json"); expect(result[0].specs).toContain("main.tsp"); expect(result[0].specs).toContain("client.tsp"); - expect(result[0].readmeMd).toBe("specification/apicenter/data-plane/readme.md"); + expect(result[0].readmeMd).toBe(path.normalize("specification/apicenter/data-plane/readme.md")); expect(result[0].typespecProject).toBe( - "specification/apicenter/ApiCenter.DataApi/tspconfig.yaml", + path.normalize("specification/apicenter/ApiCenter.DataApi/tspconfig.yaml"), ); }); diff --git a/eng/tools/spec-gen-sdk-runner/test/utils/searchRelatedTypeSpecProjectBySharedLibrary.test.ts b/eng/tools/spec-gen-sdk-runner/test/utils/searchRelatedTypeSpecProjectBySharedLibrary.test.ts index b61c36b5851e..321937a11ff6 100644 --- a/eng/tools/spec-gen-sdk-runner/test/utils/searchRelatedTypeSpecProjectBySharedLibrary.test.ts +++ b/eng/tools/spec-gen-sdk-runner/test/utils/searchRelatedTypeSpecProjectBySharedLibrary.test.ts @@ -10,17 +10,17 @@ describe("searchRelatedTypeSpecProjectBySharedLibrary", () => { test("finds related TypeSpec projects for shared libraries", () => { const sharedLibraries = [ - "specification/contosowidgetmanager/Contoso.WidgetManager.Shared/main.tsp", + path.normalize("specification/contosowidgetmanager/Contoso.WidgetManager.Shared/main.tsp"), ]; const result = searchRelatedTypeSpecProjectBySharedLibrary(sharedLibraries, { searchFileRegex: /^tspconfig\.yaml$/, specRepoFolder: repoRoot, }); - + const expectedPath = path.normalize("specification/contosowidgetmanager/Contoso.WidgetManager"); expect(Object.keys(result)).toHaveLength(1); - expect(result["specification/contosowidgetmanager/Contoso.WidgetManager"]).toBeDefined(); - expect(result["specification/contosowidgetmanager/Contoso.WidgetManager"]).toContain( + expect(result[expectedPath]).toBeDefined(); + expect(result[expectedPath]).toContain( sharedLibraries[0], ); }); @@ -35,7 +35,7 @@ describe("searchRelatedTypeSpecProjectBySharedLibrary", () => { }); test("handles non-existent directories", () => { - const sharedLibraries = ["specification/nonexistent/Shared/main.tsp"]; + const sharedLibraries = [path.normalize("specification/nonexistent/Shared/main.tsp")]; const result = searchRelatedTypeSpecProjectBySharedLibrary(sharedLibraries, { searchFileRegex: /^tspconfig\.yaml$/, diff --git a/eng/tools/spec-gen-sdk-runner/test/utils/utils.test.ts b/eng/tools/spec-gen-sdk-runner/test/utils/utils.test.ts index 8beef1e02f9e..e4ece7d9ea9f 100644 --- a/eng/tools/spec-gen-sdk-runner/test/utils/utils.test.ts +++ b/eng/tools/spec-gen-sdk-runner/test/utils/utils.test.ts @@ -14,16 +14,14 @@ const repoRoot = path.resolve(path.dirname(currentFilePath), "../../../../../"); describe("Utils", () => { describe("findFilesRecursive", () => { test("finds all tspconfig.yaml files recursively", () => { - const results = findFilesRecursive( - `${repoRoot}/specification/contosowidgetmanager`, - "tspconfig.yaml", - ); + const searchPath = path.normalize(`${repoRoot}/specification/contosowidgetmanager`); + const results = findFilesRecursive(searchPath, "tspconfig.yaml"); expect(results).toHaveLength(2); expect(results).toContain( - "specification/contosowidgetmanager/Contoso.Management/tspconfig.yaml", + path.normalize("specification/contosowidgetmanager/Contoso.Management/tspconfig.yaml"), ); expect(results).toContain( - "specification/contosowidgetmanager/Contoso.WidgetManager/tspconfig.yaml", + path.normalize("specification/contosowidgetmanager/Contoso.WidgetManager/tspconfig.yaml"), ); }); @@ -46,10 +44,15 @@ describe("Utils", () => { describe("findReadmeFiles", () => { test("finds all readme.md files in directory", () => { - const results = findReadmeFiles(`${repoRoot}/specification/contosowidgetmanager`); + const searchPath = path.normalize(`${repoRoot}/specification/contosowidgetmanager`); + const results = findReadmeFiles(searchPath); expect(results).toHaveLength(2); - expect(results).toContain("specification/contosowidgetmanager/resource-manager/readme.md"); - expect(results).toContain("specification/contosowidgetmanager/data-plane/readme.md"); + expect(results).toContain( + path.normalize("specification/contosowidgetmanager/resource-manager/readme.md"), + ); + expect(results).toContain( + path.normalize("specification/contosowidgetmanager/data-plane/readme.md"), + ); }); test("returns empty array for directory without readme files", () => { @@ -63,9 +66,9 @@ describe("Utils", () => { describe("getRelativePathFromSpecification", () => { test("extracts path from specification folder", () => { const result = getRelativePathFromSpecification( - "/repo/root/specification/apicenter/resource-manager/readme.md", + path.normalize("/repo/root/specification/apicenter/resource-manager/readme.md"), ); - expect(result).toBe("specification/apicenter/resource-manager/readme.md"); + expect(result).toBe(path.normalize("specification/apicenter/resource-manager/readme.md")); }); test("returns original path if specification is not found", () => { @@ -76,9 +79,9 @@ describe("Utils", () => { test("handles paths with multiple specification occurrences", () => { const result = getRelativePathFromSpecification( - "/repo/root/specification/old/specification/apicenter/readme.md", + path.normalize("/repo/root/specification/old/specification/apicenter/readme.md"), ); - expect(result).toBe("specification/old/specification/apicenter/readme.md"); + expect(result).toBe(path.normalize("specification/old/specification/apicenter/readme.md")); }); test("handles empty path", () => { diff --git a/package-lock.json b/package-lock.json index 6a0ea5101aef..8fdf77adb384 100644 --- a/package-lock.json +++ b/package-lock.json @@ -60,27 +60,6 @@ "undici-types": "~5.26.4" } }, - "eng/tools/node_modules/@vitest/coverage-c8": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@vitest/coverage-c8/-/coverage-c8-0.33.0.tgz", - "integrity": "sha512-DaF1zJz4dcOZS4k/neiQJokmOWqsGXwhthfmUdPGorXIQHjdPvV6JQSYhQDI41MyI8c+IieQUdIDs5XAMHtDDw==", - "deprecated": "v8 coverage is moved to @vitest/coverage-v8 package", - "dev": true, - "license": "MIT", - "dependencies": { - "@ampproject/remapping": "^2.2.1", - "c8": "^7.14.0", - "magic-string": "^0.30.1", - "picocolors": "^1.0.0", - "std-env": "^3.3.3" - }, - "funding": { - "url": "https://opencollective.com/vitest" - }, - "peerDependencies": { - "vitest": ">=0.30.0 <1" - } - }, "eng/tools/node_modules/@vitest/coverage-v8": { "version": "3.0.7", "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.0.7.tgz", @@ -338,12 +317,12 @@ }, "devDependencies": { "@types/node": "^18.19.31", - "@vitest/coverage-c8": "^0.33.0", + "@vitest/coverage-v8": "^3.0.5", "typescript": "~5.6.2", - "vitest": "^3.0.7" + "vitest": "^3.0.5" }, "engines": { - "node": ">= 18.0.0" + "node": ">=20.0.0" } }, "eng/tools/specs-model": { @@ -3792,13 +3771,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", - "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", - "dev": true, - "license": "MIT" - }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -5112,246 +5084,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/c8": { - "version": "7.14.0", - "resolved": "https://registry.npmjs.org/c8/-/c8-7.14.0.tgz", - "integrity": "sha512-i04rtkkcNcCf7zsQcSv/T9EbUn4RXQ6mropeMcjFOsQXQ0iGLAr/xT6TImQg4+U9hmNpN9XdvPkjUL1IzbgxJw==", - "dev": true, - "license": "ISC", - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@istanbuljs/schema": "^0.1.3", - "find-up": "^5.0.0", - "foreground-child": "^2.0.0", - "istanbul-lib-coverage": "^3.2.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-reports": "^3.1.4", - "rimraf": "^3.0.2", - "test-exclude": "^6.0.0", - "v8-to-istanbul": "^9.0.0", - "yargs": "^16.2.0", - "yargs-parser": "^20.2.9" - }, - "bin": { - "c8": "bin/c8.js" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/c8/node_modules/@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true, - "license": "MIT" - }, - "node_modules/c8/node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/c8/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/c8/node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/c8/node_modules/find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "dev": true, - "license": "MIT", - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/c8/node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "license": "ISC", - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/c8/node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/c8/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/c8/node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/c8/node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dev": true, - "license": "MIT", - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/c8/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "deprecated": "Rimraf versions prior to v4 are no longer supported", - "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/c8/node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true, - "license": "ISC" - }, - "node_modules/c8/node_modules/strip-ansi": { - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/c8/node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", - "dev": true, - "license": "ISC", - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/c8/node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "license": "MIT", - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/c8/node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=10" - } - }, "node_modules/cac": { "version": "6.7.14", "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz", @@ -5805,13 +5537,6 @@ "dev": true, "license": "MIT" }, - "node_modules/convert-source-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", - "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", - "dev": true, - "license": "MIT" - }, "node_modules/core-js-compat": { "version": "3.41.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.41.0.tgz", @@ -12022,21 +11747,6 @@ "dev": true, "license": "MIT" }, - "node_modules/v8-to-istanbul": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.3.0.tgz", - "integrity": "sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==", - "dev": true, - "license": "ISC", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^2.0.0" - }, - "engines": { - "node": ">=10.12.0" - } - }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",