Skip to content

Commit

Permalink
build(emitter): enable eslint (#4700)
Browse files Browse the repository at this point in the history
* build(emitter): enable eslint

- enable `npm run lint` which previously didn't work
- fix errors found by eslint
- add linter into build pipeline

resolve #4698

Co-authored-by: Mingzhe Huang (from Dev Box) <mingzhehuang@microsoft.com>
  • Loading branch information
archerzz and Mingzhe Huang (from Dev Box) committed May 13, 2024
1 parent a69b89f commit e4254f2
Show file tree
Hide file tree
Showing 23 changed files with 483 additions and 395 deletions.
4 changes: 4 additions & 0 deletions eng/pipelines/build.yml
Expand Up @@ -56,6 +56,10 @@ extends:
npm run prettier
displayName: "Emitter format check"
workingDirectory: $(Build.SourcesDirectory)/autorest.csharp/src/TypeSpec.Extension/Emitter.Csharp
- script: |
npm run lint
displayName: "Emitter linter check"
workingDirectory: $(Build.SourcesDirectory)/autorest.csharp/src/TypeSpec.Extension/Emitter.Csharp
- script: 'dotnet pack src/AutoRest.CSharp/AutoRest.CSharp.csproj -o $(Build.ArtifactStagingDirectory)/packages -warnaserror -c Release'
name: Package
displayName: 'Package'
Expand Down
4 changes: 4 additions & 0 deletions eng/pipelines/sdk-update.yml
Expand Up @@ -63,6 +63,10 @@ extends:
npm run prettier
displayName: "Emitter format check"
workingDirectory: $(Build.SourcesDirectory)/autorest.csharp/src/TypeSpec.Extension/Emitter.Csharp
- script: |
npm run lint
displayName: "Emitter linter check"
workingDirectory: $(Build.SourcesDirectory)/autorest.csharp/src/TypeSpec.Extension/Emitter.Csharp
- pwsh: ./eng/PackArtifacts.ps1 -BuildNumber $(Build.BuildNumber) -StagingDirectory $(Build.ArtifactStagingDirectory)/packages
name: Package
displayName: "Pack Artifacts"
Expand Down
1 change: 1 addition & 0 deletions eng/scripts/Test-Packages.ps1
Expand Up @@ -44,6 +44,7 @@ try {
Push-Location "$root/src/TypeSpec.Extension/Emitter.Csharp"
try {
Invoke-LoggedCommand "npm run prettier" -GroupOutput
Invoke-LoggedCommand "npm run lint" -GroupOutput
Invoke-LoggedCommand "npm run build" -GroupOutput
Invoke-LoggedCommand "npm run test" -GroupOutput
}
Expand Down
604 changes: 349 additions & 255 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 0 additions & 7 deletions src/TypeSpec.Extension/Emitter.Csharp/.eslintrc.cjs

This file was deleted.

20 changes: 20 additions & 0 deletions src/TypeSpec.Extension/Emitter.Csharp/eslint.config.js
@@ -0,0 +1,20 @@
import globals from "globals";
import pluginJs from "@eslint/js";
import tseslint from "typescript-eslint";

export default [
{
languageOptions: { globals: globals.node }
},
pluginJs.configs.recommended,
...tseslint.configs.recommended,
{
files: ["**/*.ts"],
rules: {
"@typescript-eslint/no-explicit-any": "off"
}
},
{
ignores: ["dist/"]
}
];
28 changes: 15 additions & 13 deletions src/TypeSpec.Extension/Emitter.Csharp/package.json
Expand Up @@ -25,8 +25,8 @@
"lint-typespec-library": "tsp compile . --warn-as-error --import @typespec/library-linter --no-emit",
"test": "mocha dist/test/**/*.js",
"test-official": "c8 mocha --forbid-only dist/test/**/*.js",
"lint": "eslint . --ext .ts --max-warnings=0",
"lint:fix": "eslint . --fix --ext .ts",
"lint": "eslint . --max-warnings=0",
"lint:fix": "eslint . --fix",
"prettier:fix": "prettier --write --config .prettierrc.json ./src/**/*.ts ./test/**/*.ts",
"prettier": "prettier --check --config .prettierrc.json ./src/**/*.ts ./test/**/*.ts"
},
Expand All @@ -43,32 +43,34 @@
"@azure-tools/typespec-client-generator-core": ">=0.36.0 <1.0.0",
"@typespec/compiler": ">=0.50.0 <1.0.0",
"@typespec/http": ">=0.50.0 <1.0.0",
"@typespec/openapi": ">=0.50.0 <1.0.0",
"@typespec/rest": ">=0.50.0 <1.0.0",
"@typespec/versioning": ">=0.50.0 <1.0.0",
"@typespec/openapi": ">=0.50.0 <1.0.0"
"@typespec/versioning": ">=0.50.0 <1.0.0"
},
"devDependencies": {
"@azure-tools/typespec-azure-core": "0.41.0",
"@azure-tools/typespec-client-generator-core": "0.41.8",
"@eslint/js": "^9.2.0",
"@types/lodash.isequal": "^4.5.6",
"@types/mocha": "~9.1.0",
"@types/node": "~18.13.0",
"@types/prettier": "^2.6.3",
"@typespec/compiler": "0.55.0",
"@typespec/eslint-config-typespec": "0.55.0",
"@typespec/eslint-plugin": "0.55.0",
"@typespec/http": "0.55.0",
"@typespec/json-schema": "0.55.0",
"@typespec/library-linter": "0.55.0",
"@typespec/openapi": "0.55.0",
"@typespec/rest": "0.55.0",
"@typespec/versioning": "0.55.0",
"@typespec/openapi": "0.55.0",
"@typespec/json-schema": "0.55.0",
"@types/lodash.isequal": "^4.5.6",
"@types/mocha": "~9.1.0",
"@types/node": "~18.13.0",
"@types/prettier": "^2.6.3",
"c8": "~7.11.0",
"eslint": "^8.12.0",
"eslint": "^8.57.0",
"globals": "^15.2.0",
"lodash.isequal": "^4.5.0",
"mocha": "~9.2.0",
"prettier": "~3.0.3",
"rimraf": "~3.0.2",
"typescript": "~5.1.5"
"typescript": "~5.1.5",
"typescript-eslint": "^7.8.0"
}
}
Expand Up @@ -45,7 +45,6 @@ import {
import { InputPrimitiveTypeKind } from "../type/inputPrimitiveTypeKind.js";
import { RequestLocation } from "../type/requestLocation.js";
import { Usage } from "../type/usage.js";
import { getExternalDocs } from "./decorators.js";
import { logger } from "./logger.js";
import { getUsages, navigateModels } from "./model.js";
import { loadOperation } from "./operation.js";
Expand Down Expand Up @@ -81,7 +80,6 @@ export function createModelForService(
sdkContext: SdkContext<NetEmitterOptions>,
service: Service
): CodeModel {
const emitterOptions = resolveOptions(sdkContext.emitContext);
const program = sdkContext.emitContext.program;
const serviceNamespaceType = service.type;

Expand All @@ -107,7 +105,6 @@ export function createModelForService(
: undefined;

const description = getDoc(program, serviceNamespaceType);
const externalDocs = getExternalDocs(sdkContext, serviceNamespaceType);

const servers = getServers(program, serviceNamespaceType);
const namespace = getNamespaceFullName(serviceNamespaceType) || "client";
Expand Down Expand Up @@ -232,7 +229,7 @@ export function createModelForService(
client as SdkClient
);
for (const dpgGroup of dpgOperationGroups) {
var subClient = emitClient(dpgGroup, client);
const subClient = emitClient(dpgGroup, client);
clients.push(subClient);
addChildClients(context, dpgGroup, clients);
}
Expand All @@ -243,12 +240,12 @@ export function createModelForService(
return client.name;
}

var pathParts = client.groupPath.split(".");
const pathParts = client.groupPath.split(".");
if (pathParts?.length >= 3) {
return pathParts.slice(pathParts.length - 2).join("");
}

var clientName = getLibraryName(sdkContext, client.type);
const clientName = getLibraryName(sdkContext, client.type);
if (
clientName === "Models" &&
resolveOptions(sdkContext.emitContext)["model-namespace"] !== false
Expand Down
7 changes: 3 additions & 4 deletions src/TypeSpec.Extension/Emitter.Csharp/src/lib/converter.ts
Expand Up @@ -247,7 +247,7 @@ export function fromSdkModelType(
return [modelProperty];
}

var flattenedProperties: InputModelProperty[] = [];
let flattenedProperties: InputModelProperty[] = [];
const modelPropertyType = propertyType as SdkBodyModelPropertyType;
const childPropertiesToFlatten = (
modelPropertyType.type as SdkModelType
Expand Down Expand Up @@ -301,7 +301,7 @@ export function fromSdkEnumType(
enums: Map<string, InputEnumType>,
addToCollection: boolean = true
): InputEnumType {
let enumName = enumType.name;
const enumName = enumType.name;
let inputEnumType = enums.get(enumName);
if (inputEnumType === undefined) {
const newInputEnumType: InputEnumType = {
Expand Down Expand Up @@ -666,7 +666,6 @@ function fromScalarType(scalarType: SdkType): InputPrimitiveType {
}

function fromIntrinsicType(scalarType: SdkType): InputIntrinsicType {
const name = (scalarType.__raw! as IntrinsicType).name;
return {
Kind: InputTypeKind.Intrinsic,
Name: getCSharpInputTypeKindByIntrinsic(
Expand All @@ -682,7 +681,7 @@ function fromUnionType(
models: Map<string, InputModelType>,
enums: Map<string, InputEnumType>
): InputUnionType | InputType {
let itemTypes: InputType[] = [];
const itemTypes: InputType[] = [];
for (const value of union.values) {
const inputType = fromSdkType(value, context, models, enums);
itemTypes.push(inputType);
Expand Down
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

import { DecoratedType, Operation, Program, Type } from "@typespec/compiler";
import { DecoratedType, Operation, Type } from "@typespec/compiler";
import { ExternalDocs } from "../type/externalDocs.js";
import { SdkContext } from "@azure-tools/typespec-client-generator-core";

Expand Down
2 changes: 1 addition & 1 deletion src/TypeSpec.Extension/Emitter.Csharp/src/lib/logger.ts
Expand Up @@ -11,7 +11,7 @@ export enum LoggerLevel {
VERBOSE = "verbose"
}

export var logger: winston.Logger = winston.createLogger({
export const logger: winston.Logger = winston.createLogger({
transports: [
new winston.transports.Console({
level: LoggerLevel.INFO
Expand Down
14 changes: 6 additions & 8 deletions src/TypeSpec.Extension/Emitter.Csharp/src/lib/model.ts
Expand Up @@ -27,7 +27,6 @@ import {
getQueryParamName,
isStatusCode
} from "@typespec/http";
import { getResourceOperation } from "@typespec/rest";
import { NetEmitterOptions } from "../options.js";
import {
fromSdkEnumType,
Expand Down Expand Up @@ -151,15 +150,15 @@ export function getUsages(
for (const type of usages.types) {
let typeName = "";
if ("name" in type) typeName = type.name ?? "";
let effectiveType = type;
const effectiveType = type;
if (type.kind === "Enum") {
typeName = getTypeName(context, type);
}
if (type.kind === "Model") {
typeName = getTypeName(context, effectiveType as Model);
}
if (type.kind === "Union") {
let clientType = getClientType(context, type); // TODO -- we should also pass in an operation as well
const clientType = getClientType(context, type); // TODO -- we should also pass in an operation as well
if (clientType.kind === "enum" && clientType.isFixed === false) {
typeName = clientType.name;
}
Expand Down Expand Up @@ -192,9 +191,8 @@ export function getUsages(
}

for (const op of ops) {
const resourceOperation = getResourceOperation(program, op.operation);
if (!op.parameters.body?.parameter && op.parameters.body?.type) {
var effectiveBodyType = undefined;
let effectiveBodyType = undefined;
const affectTypes: Set<string> = new Set<string>();
effectiveBodyType = getEffectiveSchemaType(
context,
Expand Down Expand Up @@ -279,7 +277,7 @@ export function getUsages(
// iterate all models to find if it contains literal type properties
for (const [name, model] of modelMap) {
// get the usage of this model
let usage = usagesMap.get(name);
const usage = usagesMap.get(name);
for (const prop of model.Properties) {
const type = prop.Type;
if (!isInputLiteralType(type)) continue;
Expand Down Expand Up @@ -333,14 +331,14 @@ export function getUsages(
result.push(getTypeName(context, derivedModel));
result.push(...getAllEffectedModels(derivedModel, visited));
}
for (const [_, prop] of model.properties) {
for (const prop of model.properties.values()) {
if (prop.type.kind === "Model") {
result.push(...getAllEffectedModels(prop.type, visited));
}
}
/*propagate usage to the property type of the base model. */
if (model.baseModel) {
for (const [_, prop] of model.baseModel.properties) {
for (const prop of model.baseModel.properties.values()) {
if (prop.type.kind === "Model") {
result.push(
...getAllEffectedModels(prop.type, visited)
Expand Down
6 changes: 3 additions & 3 deletions src/TypeSpec.Extension/Emitter.Csharp/src/lib/operation.ts
Expand Up @@ -112,7 +112,7 @@ export function loadOperation(
typespecParameters.body.type
);
if (effectiveBodyType.kind === "Model") {
let bodyParameter = loadBodyParameter(
const bodyParameter = loadBodyParameter(
sdkContext,
effectiveBodyType
);
Expand All @@ -127,7 +127,7 @@ export function loadOperation(
) {
// give body type a name
bodyParameter.Type.Name = `${capitalize(op.name)}Request`;
var bodyModelType = bodyParameter.Type as InputModelType;
const bodyModelType = bodyParameter.Type as InputModelType;
bodyModelType.Usage = Usage.Input;
// update models cache
models.delete("");
Expand Down Expand Up @@ -403,7 +403,7 @@ export function loadOperation(
return undefined;
}

var bodyType = undefined;
let bodyType = undefined;
if (
op.verb !== "delete" &&
metadata.finalResult !== undefined &&
Expand Down
Expand Up @@ -5,7 +5,6 @@ import { ServiceAuthentication } from "@typespec/http";
import { InputApiKeyAuth } from "../type/inputApiKeyAuth.js";
import { InputAuth } from "../type/inputAuth.js";
import { InputOAuth2Auth } from "../type/inputOAuth2Auth.js";
import { Logger } from "winston";
import { logger } from "./logger.js";

export function processServiceAuthentication(
Expand All @@ -31,21 +30,23 @@ export function processServiceAuthentication(
}
break;
case "http":
const schemeOrApiKeyPrefix = scheme.scheme;
if (schemeOrApiKeyPrefix === "basic") {
logger.warn(
`{schemeOrApiKeyPrefix} auth method is currently not supported.`
);
} else if (schemeOrApiKeyPrefix === "bearer") {
auth.ApiKey = {
Name: "Authorization",
Prefix: "Bearer"
} as InputApiKeyAuth;
} else {
auth.ApiKey = {
Name: "Authorization",
Prefix: schemeOrApiKeyPrefix
} as InputApiKeyAuth;
{
const schemeOrApiKeyPrefix = scheme.scheme;
if (schemeOrApiKeyPrefix === "basic") {
logger.warn(
`{schemeOrApiKeyPrefix} auth method is currently not supported.`
);
} else if (schemeOrApiKeyPrefix === "bearer") {
auth.ApiKey = {
Name: "Authorization",
Prefix: "Bearer"
} as InputApiKeyAuth;
} else {
auth.ApiKey = {
Name: "Authorization",
Prefix: schemeOrApiKeyPrefix
} as InputApiKeyAuth;
}
}
break;
default:
Expand Down
19 changes: 2 additions & 17 deletions src/TypeSpec.Extension/Emitter.Csharp/src/lib/typespecServer.ts
@@ -1,7 +1,7 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

import { getDoc, getFormat, Program, Type } from "@typespec/compiler";
import { getDoc } from "@typespec/compiler";
import { HttpServer } from "@typespec/http";
import { InputConstant } from "../type/inputConstant.js";
import { InputOperationParameterKind } from "../type/inputOperationParameterKind.js";
Expand All @@ -14,7 +14,7 @@ import {
} from "../type/inputType.js";
import { InputPrimitiveTypeKind } from "../type/inputPrimitiveTypeKind.js";
import { RequestLocation } from "../type/requestLocation.js";
import { getInputType } from "./model.js";
import { getDefaultValue, getInputType } from "./model.js";
import { SdkContext } from "@azure-tools/typespec-client-generator-core";
import { InputTypeKind } from "../type/inputTypeKind.js";
import { NetEmitterOptions } from "../options.js";
Expand All @@ -25,21 +25,6 @@ export interface TypeSpecServer {
parameters: InputParameter[];
}

function getDefaultValue(type: Type): any {
switch (type.kind) {
case "String":
return type.value;
case "Number":
return type.value;
case "Boolean":
return type.value;
case "Tuple":
return type.values.map(getDefaultValue);
default:
return undefined;
}
}

export function resolveServers(
context: SdkContext<NetEmitterOptions>,
servers: HttpServer[],
Expand Down

0 comments on commit e4254f2

Please sign in to comment.