forked from Azure/azure-rest-api-specs
-
Notifications
You must be signed in to change notification settings - Fork 8
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3598 from wanlwanl/wanl/adapt-new-rules-to-old-rules
[TSV] adapt new rules to old rules
- Loading branch information
Showing
32 changed files
with
2,725 additions
and
278 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
{ | ||
"name": "@azure-tools/eslint-plugin-tsv", | ||
"private": true, | ||
"type": "module", | ||
"main": "src/index.js", | ||
"dependencies": { | ||
"ajv": "^8.17.1", | ||
"yaml-eslint-parser": "^1.2.3" | ||
}, | ||
"peerDependencies": { | ||
"eslint": ">=9.0.0" | ||
}, | ||
"devDependencies": { | ||
"@types/node": "^18.19.31", | ||
"@vitest/coverage-v8": "^2.0.4", | ||
"eslint": "^9.17.0", | ||
"memfs": "^4.15.0", | ||
"rimraf": "^5.0.10", | ||
"typescript": "~5.6.2", | ||
"vitest": "^2.0.4" | ||
}, | ||
"scripts": { | ||
"build": "tsc --build", | ||
"cbt": "npm run clean && npm run build && npm run test:ci", | ||
"clean": "rimraf ./dist ./temp", | ||
"test": "vitest", | ||
"test:ci": "vitest run --coverage --reporter=verbose" | ||
}, | ||
"engines": { | ||
"node": ">= 18.0.0" | ||
} | ||
} |
117 changes: 117 additions & 0 deletions
117
eng/tools/eslint-plugin-tsv/src/config/config-schema.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,117 @@ | ||
// Copied from https://github.com/microsoft/typespec/blob/main/packages/compiler/src/config/config-schema.ts | ||
|
||
import type { JSONSchemaType } from "ajv"; | ||
import { EmitterOptions, TypeSpecRawConfig } from "./types.js"; | ||
|
||
export const emitterOptionsSchema: JSONSchemaType<EmitterOptions> = { | ||
type: "object", | ||
additionalProperties: true, | ||
required: [], | ||
properties: { | ||
"emitter-output-dir": { type: "string", nullable: true } as any, | ||
}, | ||
}; | ||
|
||
export const TypeSpecConfigJsonSchema: JSONSchemaType<TypeSpecRawConfig> = { | ||
type: "object", | ||
additionalProperties: false, | ||
properties: { | ||
extends: { | ||
type: "string", | ||
nullable: true, | ||
}, | ||
"environment-variables": { | ||
type: "object", | ||
nullable: true, | ||
required: [], | ||
additionalProperties: { | ||
type: "object", | ||
properties: { | ||
default: { type: "string" }, | ||
}, | ||
required: ["default"], | ||
}, | ||
}, | ||
parameters: { | ||
type: "object", | ||
nullable: true, | ||
required: [], | ||
additionalProperties: { | ||
type: "object", | ||
properties: { | ||
default: { type: "string" }, | ||
}, | ||
required: ["default"], | ||
}, | ||
}, | ||
|
||
"output-dir": { | ||
type: "string", | ||
nullable: true, | ||
}, | ||
"warn-as-error": { | ||
type: "boolean", | ||
nullable: true, | ||
}, | ||
trace: { | ||
oneOf: [ | ||
{ type: "string" }, | ||
{ | ||
type: "array", | ||
items: { type: "string" }, | ||
}, | ||
], | ||
} as any, // Issue with AJV optional property typing https://github.com/ajv-validator/ajv/issues/1664 | ||
imports: { | ||
type: "array", | ||
nullable: true, | ||
items: { type: "string" }, | ||
}, | ||
emit: { | ||
type: "array", | ||
nullable: true, | ||
items: { type: "string" }, | ||
}, | ||
options: { | ||
type: "object", | ||
nullable: true, | ||
required: [], | ||
additionalProperties: emitterOptionsSchema, | ||
}, | ||
emitters: { | ||
type: "object", | ||
nullable: true, | ||
deprecated: true, | ||
required: [], | ||
additionalProperties: { | ||
oneOf: [{ type: "boolean" }, emitterOptionsSchema], | ||
}, | ||
}, | ||
|
||
linter: { | ||
type: "object", | ||
nullable: true, | ||
required: [], | ||
additionalProperties: false, | ||
properties: { | ||
extends: { | ||
type: "array", | ||
nullable: true, | ||
items: { type: "string" }, | ||
}, | ||
enable: { | ||
type: "object", | ||
required: [], | ||
nullable: true, | ||
additionalProperties: { type: "boolean" }, | ||
}, | ||
disable: { | ||
type: "object", | ||
required: [], | ||
nullable: true, | ||
additionalProperties: { type: "string" }, | ||
}, | ||
}, | ||
} as any, // ajv type system doesn't like the string templates | ||
}, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,112 @@ | ||
// Copied from https://github.com/microsoft/typespec/blob/main/packages/compiler/src/config/types.ts | ||
|
||
import type { Diagnostic, RuleRef } from "@typespec/compiler"; | ||
import type { YamlScript } from "../yaml/types.js"; | ||
|
||
/** | ||
* Represent the normalized user configuration. | ||
*/ | ||
export interface TypeSpecConfig { | ||
/** | ||
* Project root. | ||
*/ | ||
projectRoot: string; | ||
|
||
/** Yaml file used in this configuration. */ | ||
file?: YamlScript; | ||
|
||
/** | ||
* Path to the config file used to create this configuration. | ||
*/ | ||
filename?: string; | ||
|
||
/** | ||
* Diagnostics reported while loading the configuration | ||
*/ | ||
diagnostics: Diagnostic[]; | ||
|
||
/** | ||
* Path to another TypeSpec config to extend. | ||
*/ | ||
extends?: string; | ||
|
||
/** | ||
* Environment variables configuration | ||
*/ | ||
environmentVariables?: Record<string, ConfigEnvironmentVariable>; | ||
|
||
/** | ||
* Parameters that can be used | ||
*/ | ||
parameters?: Record<string, ConfigParameter>; | ||
|
||
/** | ||
* Treat warning as error. | ||
*/ | ||
warnAsError?: boolean; | ||
|
||
/** | ||
* Output directory | ||
*/ | ||
outputDir: string; | ||
|
||
/** | ||
* Trace options. | ||
*/ | ||
trace?: string[]; | ||
|
||
/** | ||
* Additional imports. | ||
*/ | ||
imports?: string[]; | ||
|
||
/** | ||
* Name of emitters or path to emitters that should be used. | ||
*/ | ||
emit?: string[]; | ||
|
||
/** | ||
* Name of emitters or path to emitters that should be used. | ||
*/ | ||
options?: Record<string, EmitterOptions>; | ||
|
||
linter?: LinterConfig; | ||
} | ||
|
||
/** | ||
* Represent the configuration that can be provided in a config file. | ||
*/ | ||
export interface TypeSpecRawConfig { | ||
extends?: string; | ||
"environment-variables"?: Record<string, ConfigEnvironmentVariable>; | ||
parameters?: Record<string, ConfigParameter>; | ||
|
||
"warn-as-error"?: boolean; | ||
"output-dir"?: string; | ||
trace?: string | string[]; | ||
imports?: string[]; | ||
|
||
emit?: string[]; | ||
options?: Record<string, EmitterOptions>; | ||
emitters?: Record<string, boolean | EmitterOptions>; | ||
|
||
linter?: LinterConfig; | ||
} | ||
|
||
export interface ConfigEnvironmentVariable { | ||
default: string; | ||
} | ||
|
||
export interface ConfigParameter { | ||
default: string; | ||
} | ||
|
||
export type EmitterOptions = Record<string, unknown> & { | ||
"emitter-output-dir"?: string; | ||
}; | ||
|
||
export interface LinterConfig { | ||
extends?: RuleRef[]; | ||
enable?: Record<RuleRef, boolean>; | ||
disable?: Record<RuleRef, string>; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import parser from "yaml-eslint-parser"; | ||
import { NamedESLint } from "./interfaces/named-eslint.js"; | ||
import emitAutorest from "./rules/emit-autorest.js"; | ||
import kebabCaseOrg from "./rules/kebab-case-org.js"; | ||
import tspconfigValidationRules from "./rules/tspconfig-validation-rules.js"; | ||
|
||
const plugin: NamedESLint.Plugin = { | ||
configs: { recommended: {} }, | ||
name: "tsv", | ||
rules: { | ||
[kebabCaseOrg.name]: kebabCaseOrg, | ||
[emitAutorest.name]: emitAutorest, | ||
}, | ||
}; | ||
|
||
plugin.configs.recommended = { | ||
plugins: { | ||
[plugin.name]: plugin, | ||
}, | ||
files: ["*.yaml", "**/*.yaml"], | ||
rules: { | ||
[`${plugin.name}/${kebabCaseOrg.name}`]: "error", | ||
[`${plugin.name}/${emitAutorest.name}`]: "error", | ||
}, | ||
languageOptions: { | ||
parser: parser, | ||
}, | ||
}; | ||
|
||
tspconfigValidationRules.forEach((rule) => { | ||
plugin.rules![rule.name] = rule; | ||
plugin.configs.recommended.rules![`${plugin.name}/${rule.name}`] = "error"; | ||
}); | ||
|
||
export default plugin; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
import { ESLint } from "eslint"; | ||
import tsvPlugin from "./eslint-plugin-tsv.js"; | ||
|
||
export { ESLint }; | ||
export default tsvPlugin; |
17 changes: 17 additions & 0 deletions
17
eng/tools/eslint-plugin-tsv/src/interfaces/named-eslint.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
import { ESLint, Linter, Rule } from "eslint"; | ||
|
||
// ESLint with names for convenience | ||
|
||
export namespace NamedRule { | ||
export interface RuleModule extends Rule.RuleModule { | ||
name: string; | ||
} | ||
} | ||
|
||
export namespace NamedESLint { | ||
export interface Plugin extends ESLint.Plugin { | ||
configs: { recommended: Linter.Config }; | ||
name: string; | ||
rules?: Record<string, NamedRule.RuleModule>; | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
eng/tools/eslint-plugin-tsv/src/interfaces/rule-interfaces.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import { Rule } from "eslint"; | ||
import { TypeSpecConfig } from "../config/types.js"; | ||
|
||
export enum KeyType { | ||
EmitterOption, | ||
Parameter, | ||
} | ||
|
||
export interface RuleDocument { | ||
description: string; | ||
error: string; | ||
action: string; | ||
example: string; | ||
} | ||
|
||
export interface RuleInfo { | ||
name: string; | ||
documentation: RuleDocument; | ||
functions: { | ||
messages: () => { [messageId: string]: string } | undefined; | ||
condition: (tspconfig: TypeSpecConfig, context: Rule.RuleContext) => boolean; | ||
validation: (tspconfig: TypeSpecConfig, context: Rule.RuleContext, node: Rule.Node) => void; | ||
}; | ||
} | ||
|
||
export interface CreateCodeGenSDKRuleArgs { | ||
rule: string; | ||
type: KeyType; | ||
key: string; | ||
expectedValue: string | boolean | RegExp; | ||
exampleValue: string | boolean; | ||
extraExplanation?: string; | ||
condition?: (tspconfig: TypeSpecConfig, context: Rule.RuleContext) => boolean; | ||
} |
Oops, something went wrong.