From 3599d4894bbab37ae668df42fe8d1ef7b2d0d99b Mon Sep 17 00:00:00 2001 From: Max Reichmann Date: Tue, 19 Mar 2024 18:01:40 +0100 Subject: [PATCH] feat: Add detection for root files (e.g. ui5.yaml) - Add js-yaml npm library for YAML-parsing (https://www.npmjs.com/package/js-yaml) --- package-lock.json | 199 +++++++++--------- package.json | 3 + src/linter/lintWorkspace.ts | 2 + src/linter/yaml/UI5YamlLinter.ts | 87 ++++++++ src/linter/yaml/linter.ts | 29 +++ src/untyped.d.ts | 1 + src/utils/deprecatedLibs.ts | 22 ++ .../projects/com.ui5.troublesome.app/ui5.yaml | 11 + .../library.with.custom.paths/ui5.yaml | 1 + .../linter/rules/NoDeprecatedApi/ui5.yaml | 11 + .../xml/snapshots/transpiler.ts.snap | Bin 0 -> 5366 bytes test/lib/linter/UI5YamlLinter.ts | 52 +++++ test/lib/linter/_linterHelper.ts | 5 +- .../rules/snapshots/NoDeprecatedApi.ts.md | 6 + .../rules/snapshots/NoDeprecatedApi.ts.snap | Bin 6655 -> 6669 bytes test/lib/linter/snapshots/linter.ts.md | 34 +++ test/lib/utils/deprecatedLibs.ts | 27 +++ 17 files changed, 392 insertions(+), 98 deletions(-) create mode 100644 src/linter/yaml/UI5YamlLinter.ts create mode 100644 src/linter/yaml/linter.ts create mode 100644 src/utils/deprecatedLibs.ts create mode 100644 test/fixtures/linter/projects/com.ui5.troublesome.app/ui5.yaml create mode 100644 test/fixtures/linter/rules/NoDeprecatedApi/ui5.yaml create mode 100644 test/lib/detectors/transpilers/xml/snapshots/transpiler.ts.snap create mode 100644 test/lib/linter/UI5YamlLinter.ts create mode 100644 test/lib/utils/deprecatedLibs.ts diff --git a/package-lock.json b/package-lock.json index 1c4e69152..47e089906 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,8 +16,10 @@ "@ui5/logger": "^3.0.0", "@ui5/project": "^3.9.1", "chalk": "^5.3.0", + "data-with-position": "^0.5.0", "figures": "^6.1.0", "he": "^1.2.0", + "js-yaml": "^4.1.0", "json-source-map": "^0.6.1", "sax-wasm": "^2.2.4", "typescript": "5.3.x", @@ -35,6 +37,7 @@ "@istanbuljs/nyc-config-typescript": "^1.0.2", "@stylistic/eslint-plugin": "^1.7.0", "@types/he": "^1.2.3", + "@types/js-yaml": "^4.0.9", "@types/node": "^20.12.5", "@types/sinon": "^17.0.3", "@types/update-notifier": "^6.0.8", @@ -1127,12 +1130,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@eslint/eslintrc/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -1158,18 +1155,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@eslint/eslintrc/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -1345,6 +1330,15 @@ "node": ">=8" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -1358,6 +1352,19 @@ "node": ">=8" } }, + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", @@ -2766,6 +2773,12 @@ "@types/sizzle": "*" } }, + "node_modules/@types/js-yaml": { + "version": "4.0.9", + "resolved": "https://registry.npmjs.org/@types/js-yaml/-/js-yaml-4.0.9.tgz", + "integrity": "sha512-k4MGaQl5TGo/iipqb2UDG2UwjXziSWkh0uysQelTlJpX1qGlpUZYm8PnO4DxG1qBomtJUdYJ6qR6xdIah10JLg==", + "dev": true + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -3576,11 +3589,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@ui5/project/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, "node_modules/@ui5/project/node_modules/escape-string-regexp": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", @@ -3610,17 +3618,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/@ui5/project/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/@ui5/project/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -3886,13 +3883,9 @@ } }, "node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" }, "node_modules/array-differ": { "version": "3.0.0", @@ -5098,24 +5091,6 @@ "typescript": ">=4" } }, - "node_modules/cosmiconfig/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, - "node_modules/cosmiconfig/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -5216,6 +5191,14 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/data-with-position": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/data-with-position/-/data-with-position-0.5.0.tgz", + "integrity": "sha512-GhsgEIPWk7WCAisjwBkOjvPqpAlVUOSl1CTmy9KyhVMG1wxl29Zj5+J71WhQ/KgoJS/Psxq6Cnioz3xdBjeIWQ==", + "dependencies": { + "yaml-ast-parser": "^0.0.43" + } + }, "node_modules/date-time": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/date-time/-/date-time-3.1.0.tgz", @@ -5393,6 +5376,15 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/depcheck/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, "node_modules/depcheck/node_modules/camelcase": { "version": "6.3.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", @@ -5450,6 +5442,19 @@ "node": ">=10" } }, + "node_modules/depcheck/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/depcheck/node_modules/minimatch": { "version": "7.4.6", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", @@ -5494,6 +5499,15 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/depcheck/node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, "node_modules/depcheck/node_modules/yargs": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", @@ -5934,12 +5948,6 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/eslint/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", - "dev": true - }, "node_modules/eslint/node_modules/brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -6027,18 +6035,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/eslint/node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dev": true, - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -7708,13 +7704,11 @@ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" + "argparse": "^2.0.1" }, "bin": { "js-yaml": "bin/js-yaml.js" @@ -8296,11 +8290,6 @@ "markdown-it": "*" } }, - "node_modules/markdown-it/node_modules/argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, "node_modules/markdown-it/node_modules/entities": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/entities/-/entities-2.1.0.tgz", @@ -12076,6 +12065,28 @@ "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, + "node_modules/supertap/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/supertap/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -12940,14 +12951,10 @@ "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", "dev": true }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true, - "engines": { - "node": ">= 6" - } + "node_modules/yaml-ast-parser": { + "version": "0.0.43", + "resolved": "https://registry.npmjs.org/yaml-ast-parser/-/yaml-ast-parser-0.0.43.tgz", + "integrity": "sha512-2PTINUwsRqSd+s8XxKaJWQlUuEMHJQyEuh2edBbW8KNJz0SJPwUSD2zRWqezFEdN7IzAgeuYHFUCF7o8zRdZ0A==" }, "node_modules/yargs": { "version": "17.7.2", diff --git a/package.json b/package.json index 01c8e572d..342031786 100644 --- a/package.json +++ b/package.json @@ -66,8 +66,10 @@ "@ui5/logger": "^3.0.0", "@ui5/project": "^3.9.1", "chalk": "^5.3.0", + "data-with-position": "^0.5.0", "figures": "^6.1.0", "he": "^1.2.0", + "js-yaml": "^4.1.0", "json-source-map": "^0.6.1", "sax-wasm": "^2.2.4", "typescript": "5.3.x", @@ -82,6 +84,7 @@ "@istanbuljs/nyc-config-typescript": "^1.0.2", "@stylistic/eslint-plugin": "^1.7.0", "@types/he": "^1.2.3", + "@types/js-yaml": "^4.0.9", "@types/node": "^20.12.5", "@types/sinon": "^17.0.3", "@types/update-notifier": "^6.0.8", diff --git a/src/linter/lintWorkspace.ts b/src/linter/lintWorkspace.ts index 61decabeb..868db2c53 100644 --- a/src/linter/lintWorkspace.ts +++ b/src/linter/lintWorkspace.ts @@ -2,6 +2,7 @@ import {AbstractAdapter} from "@ui5/fs"; import lintXml from "./xmlTemplate/linter.js"; import lintJson from "./manifestJson/linter.js"; import lintHtml from "./html/linter.js"; +import lintUI5Yaml from "./yaml/linter.js"; import {taskStart} from "../util/perf.js"; import TypeLinter from "./ui5Types/TypeLinter.js"; import LinterContext, {LintResult, LinterParameters, LinterOptions} from "./LinterContext.js"; @@ -20,6 +21,7 @@ export default async function lintWorkspace( lintXml(params), lintJson(params), lintHtml(params), + lintUI5Yaml(params), ]); const typeLinter = new TypeLinter(params); diff --git a/src/linter/yaml/UI5YamlLinter.ts b/src/linter/yaml/UI5YamlLinter.ts new file mode 100644 index 000000000..425a9efa2 --- /dev/null +++ b/src/linter/yaml/UI5YamlLinter.ts @@ -0,0 +1,87 @@ +import {LintMessageSeverity} from "../LinterContext.js"; +import LinterContext from "../LinterContext.js"; +import deprecatedLibraries from "../../utils/deprecatedLibs.js"; +import yaml from "js-yaml"; +import {DataWithPosition, fromYaml, getPosition} from "data-with-position"; + +// file content schema of 'UI5Yaml' with only relevant properties +interface UI5YamlContentSchema { // extend for further detections + framework: { + libraries: { + name: string; + }[]; + }; +} + +interface UI5YamlContentSchemaWithPosInfo extends DataWithPosition { + framework?: { + libraries?: { + name: string; + }[]; + }; + positionKey?: { + end: { + column: number; + line: number; + }; + start: { + column: number; + line: number; + }; + }; +} + +export default class UI5YamlLinter { + #content = ""; + #yamlContentWithPosInfo: UI5YamlContentSchemaWithPosInfo = {}; + #resourcePath = ""; + #context: LinterContext; + + constructor(content: string, resourcePath: string, context: LinterContext) { + this.#content = content; + this.#resourcePath = resourcePath; + this.#context = context; + } + + // eslint-disable-next-line @typescript-eslint/require-await + async lint() { + try { + const source: UI5YamlContentSchema = this.#parseUI5Yaml(this.#content); + this.#analyzeUI5Yaml(source); + } catch (err) { + const message = err instanceof Error ? err.message : String(err); + this.#context.addLintingMessage(this.#resourcePath, { + severity: LintMessageSeverity.Error, + message, + ruleId: "ui5-linter-parsing-error", + fatal: true, + }); + } + } + + #parseUI5Yaml(fileContent: string): UI5YamlContentSchema { + // Create JS object from YAML content with position information + this.#yamlContentWithPosInfo = fromYaml(fileContent) as UI5YamlContentSchemaWithPosInfo; + // Convert YAML content to JS object + return yaml.load(fileContent) as UI5YamlContentSchema; + } + + #analyzeUI5Yaml(ui5YamlObject: UI5YamlContentSchema) { + // Check for deprecated libraries + if (ui5YamlObject?.framework?.libraries?.length) { + ui5YamlObject.framework.libraries.forEach((lib, index: number) => { + if (deprecatedLibraries.includes(lib.name)) { + const positionInfo = getPosition(this.#yamlContentWithPosInfo.framework!.libraries![index]); + this.#context.addLintingMessage(this.#resourcePath, { + ruleId: "ui5-linter-no-deprecated-api", + severity: LintMessageSeverity.Error, + fatal: undefined, + line: positionInfo.start.line, + column: positionInfo.start.column, + message: `Use of deprecated library '${lib.name}'`, + }); + } + }); + } + } +} diff --git a/src/linter/yaml/linter.ts b/src/linter/yaml/linter.ts new file mode 100644 index 000000000..805bf839e --- /dev/null +++ b/src/linter/yaml/linter.ts @@ -0,0 +1,29 @@ +import {LinterParameters} from "../LinterContext.js"; +import UI5YamlLinter from "./UI5YamlLinter.js"; +import {Resource} from "@ui5/fs"; + +export default async function lintUI5Yaml({context}: LinterParameters) { + let ui5YamlResources: Resource[]; + const pathsToLint = context.getPathsToLint(); + const reader = context.getRootReader(); + if (pathsToLint?.length) { + ui5YamlResources = []; + await Promise.all(pathsToLint.map(async (resourcePath) => { + if (!resourcePath.endsWith(".yaml")) { + return; + } + const resource = await reader.byPath(resourcePath); + if (!resource) { + throw new Error(`Resource not found: ${resourcePath}`); + } + ui5YamlResources.push(resource); + })); + } else { + ui5YamlResources = await reader.byGlob("/{ui5.yaml,*-ui5.yaml,*.ui5.yaml,ui5-*.yaml}"); + } + + await Promise.all(ui5YamlResources.map(async (resource: Resource) => { + const linter = new UI5YamlLinter(resource.getPath(), await resource.getString(), context); + await linter.lint(); + })); +} diff --git a/src/untyped.d.ts b/src/untyped.d.ts index 0e47ce5ad..368abc82e 100644 --- a/src/untyped.d.ts +++ b/src/untyped.d.ts @@ -6,6 +6,7 @@ declare module "@ui5/project" { interface Project { getNamespace: () => ProjectNamespace; getReader: (options: import("@ui5/fs").ReaderOptions) => import("@ui5/fs").AbstractReader; + getRootReader: () => import("@ui5/fs").AbstractReader; getRootPath: () => string; getSourcePath: () => string; _testPath: string; // TODO UI5 Tooling: Expose API for optional test path diff --git a/src/utils/deprecatedLibs.ts b/src/utils/deprecatedLibs.ts new file mode 100644 index 000000000..3df8c10d8 --- /dev/null +++ b/src/utils/deprecatedLibs.ts @@ -0,0 +1,22 @@ +const deprecatedLibs: string[] = [ + "sap.ca.scfld.md", + "sap.ca.ui", + "sap.fe.common", // Internal, removed in 1.110 + "sap.fe.plugins", // Internal, removed in 1.102 + "sap.fe.semantics", // Internal, removed in 1.104 + "sap.landvisz", // Removed in 1.120 + "sap.makit", + "sap.me", + "sap.sac.grid", // Removed in 1.114 + "sap.ui.commons", + "sap.ui.suite", + "sap.ui.ux3", + "sap.ui.vtm", + "sap.uiext.inbox", + "sap.webanalytics.core", + "sap.zen.commons", + "sap.zen.crosstab", + "sap.zen.dsh", +]; + +export default deprecatedLibs; diff --git a/test/fixtures/linter/projects/com.ui5.troublesome.app/ui5.yaml b/test/fixtures/linter/projects/com.ui5.troublesome.app/ui5.yaml new file mode 100644 index 000000000..dd924281f --- /dev/null +++ b/test/fixtures/linter/projects/com.ui5.troublesome.app/ui5.yaml @@ -0,0 +1,11 @@ +specVersion: '3.0' +metadata: + name: com.ui5.troublesome.app +type: application +framework: + name: OpenUI5 + version: "1.121.0" + libraries: + - name: sap.m + - name: sap.ui.core + - name: sap.landvisz diff --git a/test/fixtures/linter/projects/library.with.custom.paths/ui5.yaml b/test/fixtures/linter/projects/library.with.custom.paths/ui5.yaml index ff8a65e6d..e092fab59 100644 --- a/test/fixtures/linter/projects/library.with.custom.paths/ui5.yaml +++ b/test/fixtures/linter/projects/library.with.custom.paths/ui5.yaml @@ -12,3 +12,4 @@ framework: version: "1.120.6" libraries: - name: sap.ui.core + - name: sap.landvisz diff --git a/test/fixtures/linter/rules/NoDeprecatedApi/ui5.yaml b/test/fixtures/linter/rules/NoDeprecatedApi/ui5.yaml new file mode 100644 index 000000000..dd924281f --- /dev/null +++ b/test/fixtures/linter/rules/NoDeprecatedApi/ui5.yaml @@ -0,0 +1,11 @@ +specVersion: '3.0' +metadata: + name: com.ui5.troublesome.app +type: application +framework: + name: OpenUI5 + version: "1.121.0" + libraries: + - name: sap.m + - name: sap.ui.core + - name: sap.landvisz diff --git a/test/lib/detectors/transpilers/xml/snapshots/transpiler.ts.snap b/test/lib/detectors/transpilers/xml/snapshots/transpiler.ts.snap new file mode 100644 index 0000000000000000000000000000000000000000..33cb3f6fcd6da4a9ce664d602461f0f2879a2658 GIT binary patch literal 5366 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 { + /* Mock resource content of ui5.yaml file, + (formatted as used in src/detectors/typeChecker/index.ts - #analyzeFiles()), + (contains relevant 'framework' property and 'libraries' sub-property), + (contains only deprecated libraries) */ + const resourceContent = +`specVersion: '3.0' +metadata: + name: ava-test-ui5yamllinter +type: application +framework: + name: OpenUI5 + version: "1.121.0" + libraries: + - name: sap.ca.scfld.md + - name: sap.ca.ui + - name: sap.fe.common`; + + const resourcePath = "/ui5.js"; // '.js' due to renaming in src/detectors/typeChecker/index.ts - #analyzeFiles() + const projectPath = "test.ui5yamllinter"; + const context = new LinterContext({rootDir: projectPath}); + + // Create UI5YamlLinter instance with resource content + const linter = new UI5YamlLinter(resourceContent, resourcePath, context); + // Run UI5YamlLinter report + await linter.lint(); + + const messages = context.getLintingMessages("/ui5.js"); + + // Test returned messages + t.is(messages.length, 3, "Detection of 3 deprecated libraries expected"); + + // Test each message + t.is(messages[0].ruleId, "ui5-linter-no-deprecated-api", `RuleId is correct`); + t.is(messages[0].message, `Use of deprecated library 'sap.ca.scfld.md'`, `Message is correct`); + t.is(messages[0].column, 7, `Column is correct`); + t.is(messages[0].line, 9, `Line is correct`); + + t.is(messages[1].ruleId, "ui5-linter-no-deprecated-api", `RuleId is correct`); + t.is(messages[1].message, `Use of deprecated library 'sap.ca.ui'`, `Message is correct`); + t.is(messages[1].column, 7, `Column is correct`); + t.is(messages[1].line, 10, `Line is correct`); + + t.is(messages[2].ruleId, "ui5-linter-no-deprecated-api", `RuleId is correct`); + t.is(messages[2].message, `Use of deprecated library 'sap.fe.common'`, `Message is correct`); + t.is(messages[2].column, 7, `Column is correct`); + t.is(messages[2].line, 11, `Line is correct`); +}); diff --git a/test/lib/linter/_linterHelper.ts b/test/lib/linter/_linterHelper.ts index 60d21dce0..9050b5385 100644 --- a/test/lib/linter/_linterHelper.ts +++ b/test/lib/linter/_linterHelper.ts @@ -70,8 +70,9 @@ export function createTestsForFixtures(fixturesPath: string) { if (!fileName.endsWith(".js") && !fileName.endsWith(".xml") && !fileName.endsWith(".json") && - !fileName.endsWith(".html")) { - // Ignore non-JavaScript, non-XML, non-JSON and non-HTML files + !fileName.endsWith(".html") && + !fileName.endsWith(".yaml")) { + // Ignore non-JavaScript, non-XML, non-JSON, non-HTML and non-YAML files continue; } let testName = fileName; diff --git a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md index db9f30fc8..3e227b2f5 100644 --- a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md +++ b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.md @@ -1222,3 +1222,9 @@ Generated by [AVA](https://avajs.dev). warningCount: 0, }, ] + +## General: ui5.yaml + +> Snapshot 1 + + [] diff --git a/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap b/test/lib/linter/rules/snapshots/NoDeprecatedApi.ts.snap index bcb2e27af4c4495381c90c4c75f4f7f6f43fd3a0..6a36cac2d6af9328bcae432b06021ce966346bb6 100644 GIT binary patch delta 6326 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 delta 6312 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 diff --git a/test/lib/linter/snapshots/linter.ts.md b/test/lib/linter/snapshots/linter.ts.md index ab8fd7ad9..2b477c520 100644 --- a/test/lib/linter/snapshots/linter.ts.md +++ b/test/lib/linter/snapshots/linter.ts.md @@ -266,6 +266,23 @@ Generated by [AVA](https://avajs.dev). > Snapshot 1 [ + { + coverageInfo: [], + errorCount: 1, + fatalErrorCount: 0, + filePath: 'ui5.yaml', + messages: [ + { + column: 7, + fatal: undefined, + line: 11, + message: 'Use of deprecated library \'sap.landvisz\'', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, { coverageInfo: [], errorCount: 0, @@ -972,6 +989,23 @@ Generated by [AVA](https://avajs.dev). ], warningCount: 0, }, + { + coverageInfo: [], + errorCount: 1, + fatalErrorCount: 0, + filePath: 'ui5.yaml', + messages: [ + { + column: 7, + fatal: undefined, + line: 15, + message: 'Use of deprecated library \'sap.landvisz\'', + ruleId: 'ui5-linter-no-deprecated-api', + severity: 2, + }, + ], + warningCount: 0, + }, ] ## lint: All files of library with sap.f namespace diff --git a/test/lib/utils/deprecatedLibs.ts b/test/lib/utils/deprecatedLibs.ts new file mode 100644 index 000000000..036833577 --- /dev/null +++ b/test/lib/utils/deprecatedLibs.ts @@ -0,0 +1,27 @@ +import test from "ava"; +import deprecatedLibs from "../../../src/utils/deprecatedLibs.js"; + +test("Test Deprecated Libs constant", (t) => { + const expectedDeprecatedLibs: string[] = [ + "sap.ca.scfld.md", + "sap.ca.ui", + "sap.fe.common", // Internal, removed in 1.110 + "sap.fe.plugins", // Internal, removed in 1.102 + "sap.fe.semantics", // Internal, removed in 1.104 + "sap.landvisz", // Removed in 1.120 + "sap.makit", + "sap.me", + "sap.sac.grid", // Removed in 1.114 + "sap.ui.commons", + "sap.ui.suite", + "sap.ui.ux3", + "sap.ui.vtm", + "sap.uiext.inbox", + "sap.webanalytics.core", + "sap.zen.commons", + "sap.zen.crosstab", + "sap.zen.dsh", + ]; + t.deepEqual(deprecatedLibs, expectedDeprecatedLibs, + "Expected deprecated libraries list should match the actual list."); +});