Repository navigation
Remove ESLint and use independent Oxlint rules - #8211
gonzaloriestra wants to merge 10 commits into
Conversation
|
Warning This pull request is not mergeable via GitHub because a downstack PR is open. Once all requirements are satisfied, merge this PR as a stack on Graphite.
This stack of pull requests is managed by Graphite. Learn more about stacking. |
|
This PR seems inactive. If it's still relevant, please add a comment saying so. Otherwise, take no action. |
2b07749 to
24f882f
Compare
24f882f to
9a488dd
Compare
9a488dd to
0e8ac24
Compare
5782533 to
2be3736
Compare
|
@amcaplan thanks, I missed those commands. I only left the important ones now. |
amcaplan
left a comment
There was a problem hiding this comment.
Looks great, thanks for doing this work!
34e5a78 to
4323fcd
Compare
fec2cbc to
961b8df
Compare
160c2bd to
11b7277
Compare
isaacroldan
left a comment
There was a problem hiding this comment.
The package lint targets skip the CLI entry scripts.
🤖 Generated by the review-pr skill
| "executor": "nx:run-commands", | ||
| "options": { | ||
| "command": "pnpm eslint src 'bin/*.js'", | ||
| "command": "pnpm oxlint --config ../../oxlint.json --deny-warnings src 'bin/*.js'", |
There was a problem hiding this comment.
Oxlint doesn't expand this quoted glob, so the CLI entry scripts are skipped. I added debugger to bin/dev.js: this command passed, but passing bin directly failed as expected.
Can we use src bin in both lint and lint:fix, and add a check that covers a file in bin?
🤖 Generated by the review-pr skill
There was a problem hiding this comment.
Updated both lint and lint:fix to use src bin. Added an integration test for each configured command using a real temporary CLI with debugger in bin/dev.js. Both commands now report no-debugger; restoring the quoted glob makes both regression tests fail.
043e549 to
91ee29a
Compare
0031172 to
9f5d8c0
Compare
9f5d8c0 to
030ff58
Compare
|
| Changeset | Package |
|---|---|
remove-cli-eslint-config-dependencies.md |
'@shopify/eslint-plugin-cli': major |
Differences in type declarationsWe detected differences in the type declarations generated by Typescript for this branch compared to the baseline ('main' branch). Please, review them to ensure they are backward-compatible. Here are some important things to keep in mind:
New type declarationsWe found no new type declarations in this PR Existing type declarationspackages/cli-kit/dist/public/node/cli.d.ts@@ -1,3 +1,4 @@
+import type { OptionFlag } from '@oclif/core/interfaces';
import type { LazyCommandLoader } from './custom-oclif-loader.js';
/**
* IMPORTANT NOTE: Imports in this module are dynamic to ensure that "setupEnvironmentVariables" can dynamically
@@ -41,7 +42,7 @@ export declare const jsonFlag: {
json: import("@oclif/core/interfaces").BooleanFlag<boolean>;
};
export declare const authAliasFlag: {
- 'auth-alias': import("@oclif/core/interfaces").OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
+ 'auth-alias': OptionFlag<string | undefined, import("@oclif/core/interfaces").CustomOptions>;
};
/**
* Builds a `--port` flag that only accepts a valid port number. The flag parses its
@@ -55,7 +56,7 @@ export declare const portFlag: (options?: {
description?: string;
env?: string;
hidden?: boolean;
-}) => import("@oclif/core/interfaces").OptionFlag<number | undefined, import("@oclif/core/interfaces").CustomOptions>;
+}) => OptionFlag<number | undefined>;
/**
* Marks a flag as required when the CLI cannot prompt for a value.
*
packages/cli-kit/dist/private/node/ui/components/AutocompletePrompt.d.ts@@ -28,5 +28,5 @@ export interface AutocompletePromptProps<T> {
*/
searchDebounceMs?: number;
}
-declare function AutocompletePrompt<T>({ message, choices, infoTable, onSubmit, search, hasMorePages: initialHasMorePages, abortSignal, infoMessage, groupOrder, searchDebounceMs, }: React.PropsWithChildren<AutocompletePromptProps<T>>): ReactElement | null;
+declare const AutocompletePrompt: <T>({ message, choices, infoTable, onSubmit, search, hasMorePages: initialHasMorePages, abortSignal, infoMessage, groupOrder, searchDebounceMs, }: React.PropsWithChildren<AutocompletePromptProps<T>>) => ReactElement | null;
export { AutocompletePrompt };
\ No newline at end of file
packages/cli-kit/dist/private/node/ui/components/SelectInput.d.ts@@ -27,5 +27,5 @@ export interface Item<T> {
helperText?: string;
disabled?: boolean;
}
-declare function SelectInput<T>({ items: rawItems, initialItems, onChange, enableShortcuts, focus, emptyMessage, defaultValue, highlightedTerm, loading, errorMessage, hasMorePages, morePagesMessage, availableLines, onSubmit, inputFixedAreaRef, ref, groupOrder, }: SelectInputProps<T>): React.ReactElement | null;
+declare const SelectInput: <T>({ items: rawItems, initialItems, onChange, enableShortcuts, focus, emptyMessage, defaultValue, highlightedTerm, loading, errorMessage, hasMorePages, morePagesMessage, availableLines, onSubmit, inputFixedAreaRef, ref, groupOrder, }: SelectInputProps<T>) => React.ReactElement | null;
export { SelectInput };
\ No newline at end of file
packages/cli-kit/dist/private/node/ui/components/SelectPrompt.d.ts@@ -14,5 +14,5 @@ export interface SelectPromptProps<T> {
infoMessage?: InfoMessageProps['message'];
groupOrder?: string[];
}
-declare function SelectPrompt<T>({ message, choices, infoTable, infoMessage, onSubmit, defaultValue, abortSignal, groupOrder, }: React.PropsWithChildren<SelectPromptProps<T>>): ReactElement | null;
+declare const SelectPrompt: <T>({ message, choices, infoTable, infoMessage, onSubmit, defaultValue, abortSignal, groupOrder, }: React.PropsWithChildren<SelectPromptProps<T>>) => ReactElement | null;
export { SelectPrompt };
\ No newline at end of file
packages/cli-kit/dist/private/node/ui/components/Tasks.d.ts@@ -10,5 +10,5 @@ interface TasksProps<TContext> {
noColor?: boolean;
noProgressBar?: boolean;
}
-declare function Tasks<TContext>({ tasks, silent, onComplete, abortSignal, noColor, noProgressBar, }: React.PropsWithChildren<TasksProps<TContext>>): React.JSX.Element | null;
+declare const Tasks: <TContext>({ tasks, silent, onComplete, abortSignal, noColor, noProgressBar, }: React.PropsWithChildren<TasksProps<TContext>>) => React.JSX.Element | null;
export { Tasks };
\ No newline at end of file
packages/cli-kit/dist/private/node/ui/components/Table/Table.d.ts@@ -11,5 +11,5 @@ export interface TableProps<T extends ScalarDict> {
rows: T[];
columns: TableColumn<T>;
}
-declare function Table<T extends ScalarDict>({ rows, columns: columnsConfiguration }: TableProps<T>): React.JSX.Element;
+declare const Table: <T extends ScalarDict>({ rows, columns: columnsConfiguration }: TableProps<T>) => React.JSX.Element;
export { Table };
\ No newline at end of file
|

WHY are these changes introduced?
Remove ESLint from the CLI lint command and installed dependency tree while retaining the public CLI rules and as many existing checks as practical.
WHAT is this pull request doing?
Use native Oxlint, its type-aware checker, Prettier, and the independent rules prepared in #8725. Remove the compatibility adapter, upstream ESLint plugins, repository ESLint configuration, and associated CI/editor wiring. Workspace boundary checks read package manifests directly, removing Nx graph generation from lint startup.
Keep
@shopify/eslint-plugin-clipublic and preserve all 14 custom rule exports. Itsconfigs.configentry point now contains only CLI rules and test exemptions. Consumers must supply their own shared configs and TypeScript parser. This breaking public config change has a major changeset.Coverage audit
Against the original configuration, 243 of 301 lint rule names have replacements: 194 native counterparts, 14 retained implementations, and 35 partial independent replacements. 58 rule names have no dedicated replacement; 11 have identified coverage or overlap elsewhere in the existing toolchain. Prettier covers formatting separately. These counts do not mean 58 wholly missing capabilities, and overlap is not proof of full behavioral parity.
Existing tools cover part of this territory:
Remaining gaps include redundant type assertions, ambiguous default imports, deprecated imports and redundant paths, import checks outside the tools' scopes, advanced JSDoc semantics, consistent returns and atomic updates, Node API metadata, specialized Shopify/style policies, and Nx cycles/tags/buildability/lazy loading. Knip excludes the plugin and e2e workspaces and selected generated files. Several original rules, including consistent returns and undeclared dependencies, applied only to JavaScript; TypeScript does not replace those scopes. The shared TS config does not enable
checkJsornoImplicitReturns.Benchmark
Validation
Full lint passes on this PR and #8725, along with the uncached workspace type-check, 147 focused tests, and the coverage audit. The audit compares 1,606 files and reports no undeclared scope, option, severity, or formatting gaps. All non-e2e GitHub Actions checks pass except Breaking change detection, which flags the public plugin’s major changeset.
Checklist