Skip to content

feat: support configurable lint import sources#81

Open
QDyanbing wants to merge 2 commits intoant-design:mainfrom
QDyanbing:feat/lint-import-source
Open

feat: support configurable lint import sources#81
QDyanbing wants to merge 2 commits intoant-design:mainfrom
QDyanbing:feat/lint-import-source

Conversation

@QDyanbing
Copy link
Copy Markdown

@QDyanbing QDyanbing commented Apr 10, 2026

Summary

  • add --import-source to antd lint so wrapper package roots can be treated as antd component entrypoints
  • keep the default antd import matching behavior unchanged while allowing multiple configured sources
  • cover the new option in lint command tests and document it in spec.md

Test plan

  • npm run build
  • npx vitest run src/tests/commands/lint.test.ts

Summary by CodeRabbit

发布说明

  • 新功能

    • antd lint 添加可限制检查类别的 --only 选项(deprecated、a11y、usage、performance)
    • 新增可重复的 --import-source 选项,支持将额外导入源视为组件入口(默认仍包含 antd
  • 文档

    • 更新并新增示例,展示仅运行 deprecated 检查、输出 JSON 与 --import-source 覆盖用法
  • 测试

    • 扩展测试以覆盖多导入源配置及相关行为验证

Allow `antd lint` to recognize additional wrapper import roots via `--import-source` while keeping the default antd-only behavior unchanged.
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 10, 2026

📝 Walkthrough

Walkthrough

为 lint 命令增加了可配置的导入源(--import-source)支持,更新了 CLI 文档并在测试中新增/扩展了针对多种导入源场景的用例,同时将 lintFile 的导入检测从硬编码 antd 替换为可配置匹配逻辑。

Changes

Cohort / File(s) Summary
文档
spec.md
新增 antd lint 的示例调用(仅 deprecated 检查、JSON 输出、--import-source @shared-components`` 覆盖)并记录两个显式选项:--only <category> 与可重复的 `--import-source `。
命令实现
src/commands/lint.ts
引入 import-source 标准化、去重与匹配逻辑(支持根匹配与子路径),添加内容预检替代原先硬编码的 content.includes('antd'),并在 registerLintCommand 中增加可重复的 --import-source 选项与 action 参数传递;lintFile 接口扩展以接受 importSources
测试
src/__tests__/commands/lint.test.ts
扩展测试辅助 runLint 以接受并转换 importSources 为 CLI 标志;新增 configurable import sources 测试套件,覆盖单一源、多源、默认跳过与 minimal 模式下行为。

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 我是代码兔,跳进仓库草地里,
新增导入源,让检索更灵活,
CLI 参数排队走,测试也来聚集,
小改动连成线,lint 更会听话啰 🥕✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 12.50% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 标题清晰准确地总结了变更的主要目的:添加对 lint 命令的可配置导入源支持,与所有文件的修改内容高度一致。

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@afc163
Copy link
Copy Markdown
Member

afc163 commented Apr 10, 2026

--import-source 是啥意思?解释一下?

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (3)
src/__tests__/commands/lint.test.ts (2)

25-30: console.log mock 恢复补上 finally,避免异常路径污染后续用例。

Line 27 的 parseAsync 一旦抛错,Line 29 的 mockRestore() 不会执行,后续测试可能被连带影响。

可参考的修改
   const logSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
   const importArgs = importSources.flatMap((source) => ['--import-source', source]);
-  await program.parseAsync(['node', 'test', 'lint', ...args, ...importArgs]);
-  const output = logSpy.mock.calls.map((c) => c[0]).join('\n');
-  logSpy.mockRestore();
-  return output;
+  try {
+    await program.parseAsync(['node', 'test', 'lint', ...args, ...importArgs]);
+    return logSpy.mock.calls.map((c) => c[0]).join('\n');
+  } finally {
+    logSpy.mockRestore();
+  }
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/commands/lint.test.ts` around lines 25 - 30, The console.log
mock created via vi.spyOn(...) and assigned to logSpy should always be restored
even if program.parseAsync(...) throws; wrap the await
program.parseAsync(['node','test','lint', ...args, ...importArgs]) call in a
try/finally and call logSpy.mockRestore() in the finally block so the mock is
cleaned up on both success and error (identify logSpy, vi.spyOn(console, 'log'),
program.parseAsync, and mockRestore to locate the code to change).

610-666: 新增用例建议做单测级别临时文件清理。

当前这些 case 都会写入临时文件,但没有在每个 case 的 finallyafterEach 做清理;建议补上,减少用例间状态耦合。

As per coding guidelines "Clean up temporary files/directories created in tests using finally blocks or afterEach hooks".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/__tests__/commands/lint.test.ts` around lines 610 - 666, The tests create
temp files via makeTmpFile and read them using runLint and join(tmpDir, ...),
but they don't clean up the files which can leak state between tests; add
cleanup that removes files under tmpDir after each test (or wrap each case's
setup in try/finally) — e.g., add an afterEach hook in
src/__tests__/commands/lint.test.ts that deletes tmpDir contents (or calls the
existing cleanup utility if present) or modify each spec (like the tests named
'detects deprecated props from configured wrapper root import', 'skips wrapper
subpath default import in minimal mode', 'skips wrapper imports by default when
no import source is configured', and 'supports multiple configured import
sources') to remove files in a finally block after makeTmpFile is used so
makeTmpFile and tmpDir are always cleaned up.
src/commands/lint.ts (1)

124-126: 预检查命中条件偏宽,建议收窄以减少无效 AST 解析。

Line 125 仅用 content.includes(importSource) 会命中注释/字符串等非导入场景,导致不必要的 parseSync 开销。建议改为匹配 import/from 语句形态。

可参考的修改
+function escapeRegExp(value: string): string {
+  return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
+}
+
 function mayContainImportSource(content: string, importSources: string[]): boolean {
-  return importSources.some((importSource) => content.includes(importSource));
+  return importSources.some((importSource) => {
+    const source = escapeRegExp(importSource);
+    const pattern = new RegExp(
+      `(?:from\\s+['"]${source}(?:\\/[^'"]*)?['"]|import\\s+['"]${source}(?:\\/[^'"]*)?['"])`,
+    );
+    return pattern.test(content);
+  });
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/lint.ts` around lines 124 - 126, The pre-check in
mayContainImportSource is too broad because content.includes(...) matches
comments/strings; replace the simple substring check with a tighter pattern
match that only detects real import contexts (e.g., ES import/export with from,
static import with quotes, CommonJS require(...) and dynamic import(...)) by
testing content against a regex per importSource (or building a single regex
that escapes the importSource and matches patterns like import ... from 'X' |
export ... from 'X' | require('X') | import('X')); update mayContainImportSource
to use that pattern test to reduce false positives and unnecessary parseSync
calls.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/__tests__/commands/lint.test.ts`:
- Around line 25-30: The console.log mock created via vi.spyOn(...) and assigned
to logSpy should always be restored even if program.parseAsync(...) throws; wrap
the await program.parseAsync(['node','test','lint', ...args, ...importArgs])
call in a try/finally and call logSpy.mockRestore() in the finally block so the
mock is cleaned up on both success and error (identify logSpy, vi.spyOn(console,
'log'), program.parseAsync, and mockRestore to locate the code to change).
- Around line 610-666: The tests create temp files via makeTmpFile and read them
using runLint and join(tmpDir, ...), but they don't clean up the files which can
leak state between tests; add cleanup that removes files under tmpDir after each
test (or wrap each case's setup in try/finally) — e.g., add an afterEach hook in
src/__tests__/commands/lint.test.ts that deletes tmpDir contents (or calls the
existing cleanup utility if present) or modify each spec (like the tests named
'detects deprecated props from configured wrapper root import', 'skips wrapper
subpath default import in minimal mode', 'skips wrapper imports by default when
no import source is configured', and 'supports multiple configured import
sources') to remove files in a finally block after makeTmpFile is used so
makeTmpFile and tmpDir are always cleaned up.

In `@src/commands/lint.ts`:
- Around line 124-126: The pre-check in mayContainImportSource is too broad
because content.includes(...) matches comments/strings; replace the simple
substring check with a tighter pattern match that only detects real import
contexts (e.g., ES import/export with from, static import with quotes, CommonJS
require(...) and dynamic import(...)) by testing content against a regex per
importSource (or building a single regex that escapes the importSource and
matches patterns like import ... from 'X' | export ... from 'X' | require('X') |
import('X')); update mayContainImportSource to use that pattern test to reduce
false positives and unnecessary parseSync calls.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 1599e4bb-0790-42e6-acbd-4662d0fd860c

📥 Commits

Reviewing files that changed from the base of the PR and between c6fa1d7 and 9b7e997.

📒 Files selected for processing (3)
  • spec.md
  • src/__tests__/commands/lint.test.ts
  • src/commands/lint.ts

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 10, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.62%. Comparing base (c6fa1d7) to head (9b7e997).

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #81   +/-   ##
=======================================
  Coverage   99.62%   99.62%           
=======================================
  Files          28       28           
  Lines        1605     1618   +13     
  Branches      462      466    +4     
=======================================
+ Hits         1599     1612   +13     
  Misses          5        5           
  Partials        1        1           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new --import-source flag to the lint command, allowing users to specify additional entry points (such as component wrappers) that should be treated as antd for linting purposes. The changes include documentation updates, new test cases for configurable sources, and logic to normalize and match these sources during the linting process. Feedback was provided to generalize the performance rule against wildcard imports so that it applies to all configured import sources rather than being restricted to the default antd package.

@QDyanbing
Copy link
Copy Markdown
Author

--import-source 是啥意思?解释一下?

额外指定一组“也按 antd 组件入口来处理”的导入源

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/commands/lint.ts (1)

170-185: ⚠️ Potential issue | 🟡 Minor

性能规则提示文案会误导自定义 import source 场景

Line 184 的报错文案写死为 antd。当命中 --import-source(例如 @corp/ui)时,提示与实际 import 来源不一致,排查体验会变差。

💡 建议修复
-          report('performance', 'error', lineOf(node),
-            'Avoid wildcard import from antd. Use named imports: `import { Button } from \'antd\'`');
+          report(
+            'performance',
+            'error',
+            lineOf(node),
+            `Avoid default/namespace import from \`${source}\`. Use named imports from the configured source root.`,
+          );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/lint.ts` around lines 170 - 185, The performance rule message
hardcodes "antd", which misleads when a custom import source (e.g.
--import-source like "@corp/ui") is used; update the report call inside the
ImportSpecifier loop (the block that calls report('performance', 'error',
lineOf(node), ...)) to interpolate or include the actual import source variable
(source) in the message so it reads like "Avoid wildcard import from {source}.
Use named imports: `import { Button } from '{source}'`", ensuring proper
quoting/escaping of source and preserving the existing conditionals
(matchesImportSource, only/performance checks) and message formatting.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/commands/lint.ts`:
- Around line 339-340: The new CLI option definition for '--import-source' uses
a single English description; update it to use bilingual fields and the localize
helper: replace the single string description in the .option call with two
fields description and descriptionZh containing the English and Chinese texts
respectively, and pass the displayed text through localize(en, zh, lang) (import
or reference the localize helper from src/types.ts). Ensure the .option
invocation still uses collectImportSource and the .action signature (target,
cmdOpts) remains unchanged so behavior isn't altered.

---

Outside diff comments:
In `@src/commands/lint.ts`:
- Around line 170-185: The performance rule message hardcodes "antd", which
misleads when a custom import source (e.g. --import-source like "@corp/ui") is
used; update the report call inside the ImportSpecifier loop (the block that
calls report('performance', 'error', lineOf(node), ...)) to interpolate or
include the actual import source variable (source) in the message so it reads
like "Avoid wildcard import from {source}. Use named imports: `import { Button }
from '{source}'`", ensuring proper quoting/escaping of source and preserving the
existing conditionals (matchesImportSource, only/performance checks) and message
formatting.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 3c918f0c-d8fb-4c10-9e26-fb8868d78be5

📥 Commits

Reviewing files that changed from the base of the PR and between 9b7e997 and 124e50c.

📒 Files selected for processing (1)
  • src/commands/lint.ts

Comment on lines +339 to +340
.option('--import-source <source>', 'Treat additional import source roots as antd component entrypoints', collectImportSource, [])
.action((target: string | undefined, cmdOpts: { only?: string; importSource?: string[] }) => {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

新增 CLI 选项描述未按双语本地化规范处理

Line 339 新增用户可见文案为英文单语,未使用 localize(en, zh, lang)。建议补齐中英文并按语言选择输出。

As per coding guidelines: src/**/*.ts: Store bilingual data as paired fields (description / descriptionZh) and use localize(en, zh, lang) helper from src/types.ts to pick the appropriate language.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/commands/lint.ts` around lines 339 - 340, The new CLI option definition
for '--import-source' uses a single English description; update it to use
bilingual fields and the localize helper: replace the single string description
in the .option call with two fields description and descriptionZh containing the
English and Chinese texts respectively, and pass the displayed text through
localize(en, zh, lang) (import or reference the localize helper from
src/types.ts). Ensure the .option invocation still uses collectImportSource and
the .action signature (target, cmdOpts) remains unchanged so behavior isn't
altered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants