Skip to content

Commit 1a70fdd

Browse files
authored
chore(lint): enforce zero warnings and cleanup syntax restrictions (#22902)
1 parent b316fcc commit 1a70fdd

18 files changed

Lines changed: 21 additions & 27 deletions

eslint.config.js

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,12 @@ const commonRestrictedSyntaxRules = [
3535
message:
3636
'Do not throw string literals or non-Error objects. Throw new Error("...") instead.',
3737
},
38+
{
39+
selector:
40+
'UnaryExpression[operator="typeof"] > MemberExpression[computed=true][property.type="Literal"]',
41+
message:
42+
'Do not use typeof to check object properties. Define a TypeScript interface and a type guard function instead.',
43+
},
3844
];
3945

4046
export default tseslint.config(
@@ -133,16 +139,7 @@ export default tseslint.config(
133139
'no-cond-assign': 'error',
134140
'no-debugger': 'error',
135141
'no-duplicate-case': 'error',
136-
'no-restricted-syntax': [
137-
'error',
138-
...commonRestrictedSyntaxRules,
139-
{
140-
selector:
141-
'UnaryExpression[operator="typeof"] > MemberExpression[computed=true][property.type="Literal"]',
142-
message:
143-
'Do not use typeof to check object properties. Define a TypeScript interface and a type guard function instead.',
144-
},
145-
],
142+
'no-restricted-syntax': ['error', ...commonRestrictedSyntaxRules],
146143
'no-unsafe-finally': 'error',
147144
'no-unused-expressions': 'off', // Disable base rule
148145
'@typescript-eslint/no-unused-expressions': [

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
"test:integration:sandbox:none": "cross-env GEMINI_SANDBOX=false vitest run --root ./integration-tests",
5252
"test:integration:sandbox:docker": "cross-env GEMINI_SANDBOX=docker npm run build:sandbox && cross-env GEMINI_SANDBOX=docker vitest run --root ./integration-tests",
5353
"test:integration:sandbox:podman": "cross-env GEMINI_SANDBOX=podman vitest run --root ./integration-tests",
54-
"lint": "eslint . --cache",
54+
"lint": "eslint . --cache --max-warnings 0",
5555
"lint:fix": "eslint . --fix --ext .ts,.tsx && eslint integration-tests --fix && eslint scripts --fix && npm run format",
5656
"lint:ci": "npm run lint:all",
5757
"lint:all": "node scripts/lint.js",

packages/cli/src/nonInteractiveCli.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,7 @@ describe('runNonInteractive', () => {
11371137

11381138
expect(
11391139
processStderrSpy.mock.calls.some(
1140+
// eslint-disable-next-line no-restricted-syntax
11401141
(call) => typeof call[0] === 'string' && call[0].includes('Cancelling'),
11411142
),
11421143
).toBe(true);

packages/cli/src/test-utils/customMatchers.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ export async function toMatchSvgSnapshot(
7979
}
8080

8181
function toHaveOnlyValidCharacters(this: Assertion, buffer: TextBuffer) {
82-
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-type-assertion, @typescript-eslint/no-unsafe-assignment
82+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
8383
const { isNot } = this as any;
8484
let pass = true;
8585
const invalidLines: Array<{ line: number; content: string }> = [];
@@ -108,7 +108,6 @@ function toHaveOnlyValidCharacters(this: Assertion, buffer: TextBuffer) {
108108
};
109109
}
110110

111-
// eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion
112111
expect.extend({
113112
toHaveOnlyValidCharacters,
114113
toMatchSvgSnapshot,

packages/cli/src/test-utils/mockCommandContext.ts

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,12 @@ export const createMockCommandContext = (
3737
},
3838
services: {
3939
agentContext: null,
40-
4140
settings: {
4241
merged: defaultMergedSettings,
4342
setValue: vi.fn(),
4443
forScope: vi.fn().mockReturnValue({ settings: {} }),
4544
} as unknown as LoadedSettings,
4645
git: undefined as GitService | undefined,
47-
4846
logger: {
4947
log: vi.fn(),
5048
logMessage: vi.fn(),
@@ -53,7 +51,6 @@ export const createMockCommandContext = (
5351
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5452
} as any, // Cast because Logger is a class.
5553
},
56-
5754
ui: {
5855
addItem: vi.fn(),
5956
clear: vi.fn(),
@@ -72,7 +69,6 @@ export const createMockCommandContext = (
7269
} as any,
7370
session: {
7471
sessionShellAllowlist: new Set<string>(),
75-
7672
stats: {
7773
sessionStartTime: new Date(),
7874
lastPromptTokenCount: 0,
@@ -98,7 +94,6 @@ export const createMockCommandContext = (
9894
for (const key in source) {
9995
if (Object.prototype.hasOwnProperty.call(source, key)) {
10096
const sourceValue = source[key];
101-
10297
const targetValue = output[key];
10398

10499
if (
@@ -109,7 +104,6 @@ export const createMockCommandContext = (
109104
output[key] = merge(targetValue, sourceValue);
110105
} else {
111106
// If not, we do a direct assignment. This preserves Date objects and others.
112-
113107
output[key] = sourceValue;
114108
}
115109
}

packages/cli/src/test-utils/render.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -778,7 +778,6 @@ export async function renderHook<Result, Props>(
778778
generateSvg: () => string;
779779
}> {
780780
const result = { current: undefined as unknown as Result };
781-
782781
let currentProps = options?.initialProps as Props;
783782

784783
function TestComponent({

packages/cli/src/test-utils/settings.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ export const createMockSettings = (
4646
workspace,
4747
isTrusted,
4848
errors,
49-
5049
merged: mergedOverride,
5150
...settingsOverrides
5251
} = overrides;
@@ -61,7 +60,6 @@ export const createMockSettings = (
6160
settings: settingsOverrides,
6261
originalSettings: settingsOverrides,
6362
},
64-
6563
(workspace as any) || { path: '', settings: {}, originalSettings: {} },
6664
isTrusted ?? true,
6765
errors || [],

packages/cli/src/ui/IdeIntegrationNudge.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ describe('IdeIntegrationNudge', () => {
4242
beforeEach(() => {
4343
vi.mocked(debugLogger.warn).mockImplementation((...args) => {
4444
if (
45+
// eslint-disable-next-line no-restricted-syntax
4546
typeof args[0] === 'string' &&
4647
/was not wrapped in act/.test(args[0])
4748
) {

packages/cli/src/ui/auth/AuthInProgress.test.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ describe('AuthInProgress', () => {
4242
vi.useFakeTimers();
4343
vi.mocked(debugLogger.error).mockImplementation((...args) => {
4444
if (
45+
// eslint-disable-next-line no-restricted-syntax
4546
typeof args[0] === 'string' &&
4647
args[0].includes('was not wrapped in act')
4748
) {

packages/cli/src/ui/hooks/slashCommandProcessor.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,9 @@ export const useSlashCommandProcessor = (
505505
const props = result.props as Record<string, unknown>;
506506
if (
507507
!props ||
508+
// eslint-disable-next-line no-restricted-syntax
508509
typeof props['name'] !== 'string' ||
510+
// eslint-disable-next-line no-restricted-syntax
509511
typeof props['displayName'] !== 'string' ||
510512
!props['definition']
511513
) {

0 commit comments

Comments
 (0)