1import{_ as i,c as a,a as n,o as t}from"./app-C1L7GXRS.js";const l={};function h(e,s){return t(),a("div",null,s[0]||(s[0]=[n(`<blockquote><p>IDE é
ç½®ãè°è¯æå·§ãCI/CD æ¬å°æ¨¡æãNapCat æ¬å°é¨ç½²ä¸å¸¸è§é®é¢ææ¥ã</p></blockquote><hr><h2 id="ç®å½" tabindex="-1"><a class="header-anchor" href="#ç®å½"><span>ç®å½</span></a></h2><ul><li><a href="#ide-%E9%85%8D%E7%BD%AEvscode">IDE é
ç½®ï¼VSCodeï¼</a></li><li><a href="#%E8%B0%83%E8%AF%95%E9%85%8D%E7%BD%AE">è°è¯é
ç½®</a></li><li><a href="#pre-commit-%E8%AF%A6%E8%A7%A3">pre-commit 详解</a></li><li><a href="#cicd-%E6%9C%AC%E5%9C%B0%E6%A8%A1%E6%8B%9F">CI/CD æ¬å°æ¨¡æ</a></li><li><a href="#napcat-%E6%9C%AC%E5%9C%B0%E9%83%A8%E7%BD%B2">NapCat æ¬å°é¨ç½²</a></li><li><a href="#%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98%E6%8E%92%E6%9F%A5">常è§é®é¢ææ¥</a></li></ul><hr><h2 id="ide-é
ç½®-vscode" tabindex="-1"><a class="header-anchor" href="#ide-é
ç½®-vscode"><span>IDE é
ç½®ï¼VSCodeï¼</span></a></h2><h3 id="æ¨èæ©å±" tabindex="-1"><a class="header-anchor" href="#æ¨èæ©å±"><span>æ¨èæ©å±</span></a></h3><p>å¨ VSCode ä¸å®è£
以䏿©å±ä»¥è·å¾æä½³å¼åä½éªï¼</p><table><thead><tr><th>æ©å±</th><th>ID</th><th>ç¨é</th></tr></thead><tbody><tr><td>Python</td><td><code>ms-python.python</code></td><td>Python è¯è¨æ¯æ</td></tr><tr><td>Pylance</td><td><code>ms-python.vscode-pylance</code></td><td>ç±»åæ£æ¥ + æºè½è¡¥å
¨</td></tr><tr><td>Ruff</td><td><code>charliermarsh.ruff</code></td><td>Lint + æ ¼å¼å</td></tr><tr><td>Even Better TOML</td><td><code>tamasfe.even-better-toml</code></td><td>TOML è¯æ³é«äº®</td></tr></tbody></table><h3 id="æ¨è-settings-json" tabindex="-1"><a class="header-anchor" href="#æ¨è-settings-json"><span>æ¨è settings.json</span></a></h3><p>å¨é¡¹ç®æ ¹ç®å½å建 <code>.vscode/settings.json</code>ï¼å¦å°ä¸åå¨ï¼ï¼</p><div class="language-jsonc line-numbers-mode" data-ext="jsonc" data-title="jsonc"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">
1{</span></span> 2<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"> // Python ç¯å¢</span></span> 3<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">python.defaultInterpreterPath</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">\${workspaceFolder}/.venv/Scripts/python.exe</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 4<span class="line"></span> 5<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"> // Ruff ä½ä¸ºé»è®¤æ ¼å¼åå¨</span></span> 6<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">[python]</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> {</span></span> 7<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">editor.defaultFormatter</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">charliermarsh.ruff</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 8<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">editor.formatOnSave</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;"> true</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 9<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">editor.codeActionsOnSave</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> {</span></span> 10<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">source.fixAll.ruff</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">explicit</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 11<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">source.organizeImports.ruff</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">explicit</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span></span> 12<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> }</span></span> 13<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> },</span></span> 14<span class="line"></span> 15<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"> // Pylance ç±»åæ£æ¥</span></span> 16<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">python.analysis.typeCheckingMode</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">basic</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 17<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">python.analysis.autoImportCompletions</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;"> true</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 18<span class="line"></span> 19<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"> // æä»¶å ³è</span></span> 20<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">files.associations</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> {</span></span> 21<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">*.toml</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">toml</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span></span> 22<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> },</span></span> 23<span class="line"></span> 24<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"> // è¡å°¾ç»ä¸ LF</span></span> 25<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">files.eol</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;">\\n</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span></span> 26<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote><p><strong>Linux/macOS ç¨æ·</strong>ï¼å° <code>python.defaultInterpreterPath</code> æ¹ä¸º <code>\${workspaceFolder}/.venv/bin/python</code>ã</p></blockquote><hr><h2 id="è°è¯é ç½®" tabindex="-1"><a class="header-anchor" href="#è°è¯é ç½®"><span>è°è¯é ç½®</span></a></h2><p>å¨ <code>.vscode/launch.json</code> 䏿·»å 以ä¸é ç½®ï¼</p><div class="language-jsonc line-numbers-mode" data-ext="jsonc" data-title="jsonc"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">
26{</span></span> 27<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">version</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">0.2.0</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 28<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">configurations</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> [</span></span> 29<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> {</span></span> 30<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">name</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">NcatBot: è¿è¡ main.py</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 31<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">type</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">debugpy</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 32<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">request</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">launch</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 33<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">program</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">\${workspaceFolder}/main.py</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 34<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">cwd</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">\${workspaceFolder}</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 35<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">console</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">integratedTerminal</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 36<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">justMyCode</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;"> true</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 37<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">
37env</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> {</span></span> 38<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">PYTHONPATH</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">\${workspaceFolder}</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span></span> 39<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> }</span></span> 40<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> },</span></span> 41<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> {</span></span> 42<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">name</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">NcatBot: è¿è¡å½åæä»¶</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 43<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">type</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">debugpy</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 44<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">request</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">launch</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 45<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">program</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">\${file}</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 46<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">cwd</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">\${workspaceFolder}</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 47<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">console</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">integratedTerminal</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 48<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">justMyCode</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;"> true</span></span> 49<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> },</span></span> 50<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> {</span></span> 51<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">name</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">NcatBot: pytest å½åæä»¶</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 52<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">type</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">debugpy</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 53<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">request</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">launch</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 54<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">module</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">pytest</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 55<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">args</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> [</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">\${file}</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">-v</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">--no-cov</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">],</span></span> 56<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">cwd</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">\${workspaceFolder}</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 57<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">console</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">integratedTerminal</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 58<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">justMyCode</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">
58 false</span></span> 59<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> },</span></span> 60<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> {</span></span> 61<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">name</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">NcatBot: pytest å ¨é¨æµè¯</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 62<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">type</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">debugpy</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 63<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">request</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">launch</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 64<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">module</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">pytest</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 65<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">args</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> [</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">-v</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">--no-cov</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">],</span></span> 66<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">cwd</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">\${workspaceFolder}</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 67<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">console</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">integratedTerminal</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">,</span></span> 68<span class="line"><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;"> "</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">justMyCode</span><span style="--shiki-light:#99841877;--shiki-dark:#B8A96577;">"</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">
68 false</span></span> 69<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> }</span></span> 70<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;"> ]</span></span> 71<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">}</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p><strong>ä½¿ç¨æ¹å¼</strong>ï¼æ <code>F5</code> æå¨"è¿è¡åè°è¯"颿¿éæ©é ç½®å¯å¨ãè°è¯ pytest æ¶ä½¿ç¨ <code>--no-cov</code> é¿å è¦ççæä»¶å¹²æ°æç¹ã</p><hr><h2 id="pre-commit-详解" tabindex="-1"><a class="header-anchor" href="#pre-commit-详解"><span>pre-commit 详解</span></a></h2><h3 id="å®è£ é©å" tabindex="-1"><a class="header-anchor" href="#å®è£ é©å"><span>å®è£ é©å</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pre-commit</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> install</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><p>å®è£ åæ¯æ¬¡ <code>git commit</code> ä¼èªå¨è¿è¡ä»¥ä¸æ£æ¥ï¼</p><table><thead><tr><th>æ¥æº</th><th>æ£æ¥å 容</th></tr></thead><tbody><tr><td><strong>pre-commit-hooks</strong></td><td>å°¾é¨ç©ºç½ãæä»¶æ«å°¾æ¢è¡ãYAML/TOML è¯æ³ãAST åæ³æ§ã大æä»¶æ£æµãåå¹¶å²çªæ è®°ãç§é¥æ³é²æ£æµãdebug è¯å¥ãè¡å°¾ç»ä¸ LF</td></tr><tr><td><strong>ruff</strong></td><td>代ç lintï¼èªå¨ä¿®å¤ï¼+ æ ¼å¼å</td></tr><tr><td><strong>codespell</strong></td><td>æ¼åæ£æ¥</td></tr></tbody></table><h3 id="常è§åºæ¯" tabindex="-1"><a class="header-anchor" href="#常è§åºæ¯"><span>常è§åºæ¯</span></a></h3><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># æå¨å¯¹æææä»¶è¿è¡ï¼æ¨è馿¬¡å®è£ åæ§è¡ï¼</span></span> 72<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pre-commit</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --all-files</span></span> 73<span class="line"></span> 74<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 妿 pre-commit èªå¨ä¿®å¤äºæä»¶ï¼éè¦éæ°æå</span></span> 75<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> add</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> .</span></span> 76<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">git</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> commit</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -m</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;"> "</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;">your message</span><span style="--shiki-light:#B5695977;--shiki-dark:#C98A7D77;">"</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><div class="hint-container tip"><p class="hint-container-title">æç¤º</p><p>pre-commit èªå¨ä¿®å¤æä»¶å <code>git commit</code> ä¼ä¸æï¼è¯· <code>git add</code> ä¿®å¤åçæä»¶åéæ°æäº¤ã䏿¨èä½¿ç¨ <code>--no-verify</code> è·³è¿æ£æ¥ã</p></div><hr><h2 id="ci-cd-æ¬å°æ¨¡æ" tabindex="-1"><a class="header-anchor" href="#ci-cd-æ¬å°æ¨¡æ"><span>CI/CD æ¬å°æ¨¡æ</span></a></h2><h3 id="使ç¨-tox-å¤çæ¬æµè¯" tabindex="-1"><a class="header-anchor" href="#使ç¨-tox-å¤çæ¬æµè¯"><span>ä½¿ç¨ tox å¤çæ¬æµè¯</span></a></h3><p>tox å¯å¨æ¬å°æ¨¡æ CI çå¤ Python çæ¬æµè¯ç©éµï¼</p><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># è¿è¡ææçæ¬ï¼Python 3.12 + 3.13ï¼</span></span> 77<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> tox</span></span> 78<span class="line"></span> 79<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># æå®çæ¬</span></span> 80<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> tox</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -e</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> py312</span></span> 81<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> tox</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> -e</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> py313</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>tox é ç½®ä½äº <code>tox.ini</code>ï¼</p><div class="language-ini line-numbers-mode" data-ext="ini" data-title="ini"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">[</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">tox</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">]</span></span> 82<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">envlist</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> =</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> py312, py313</span></span> 83<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">requires</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> =</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> tox-uv</span></span> 84<span class="line"></span> 85<span class="line"><span style="--shiki-light:#999999;--shiki-dark:#666666;">[</span><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">testenv</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">]</span></span> 86<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">extras</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> =</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> dev</span></span> 87<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">commands</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> =</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> pytest --no-cov {posargs}</span></span> 88<span class="line"><span style="--shiki-light:#1E754F;--shiki-dark:#4D9375;">uv_python_preference</span><span style="--shiki-light:#999999;--shiki-dark:#666666;"> =</span><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;"> managed</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><blockquote><p>tox ä½¿ç¨ <code>tox-uv</code>
88 æä»¶éæ uvï¼ä¼èªå¨ä¸è½½æéç Python çæ¬ãå¤çæ¬æµè¯ä¸æ¯æäº¤ PR çå¿ è¦æ¡ä»¶ï¼CI ä¼èªå¨å¤çã</p></blockquote><h3 id="模æå®æ´-ci-æµç¨" tabindex="-1"><a class="header-anchor" href="#模æå®æ´-ci-æµç¨"><span>模æå®æ´ CI æµç¨</span></a></h3><p>卿¬å°æä»¥ä¸é¡ºåºæ§è¡ï¼å¯è¦ç CI çæææ£æ¥é¡¹ï¼</p><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 1. ä»£ç æ£æ¥</span></span> 89<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> ruff</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> check</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> .</span></span> 90<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> ruff</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> format</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --check</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> .</span></span> 91<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> codespell</span></span> 92<span class="line"></span> 93<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 2. ç±»åæ£æ¥</span></span> 94<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> mypy</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> ncatbot/</span></span> 95<span class="line"></span> 96<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 3. åå æµè¯</span></span> 97<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pytest</span></span> 98<span class="line"></span> 99<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># 4. å¤çæ¬æµè¯ï¼å¯éï¼</span></span> 100<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> tox</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><p>å ¨é¨éè¿åå³å¯æ¾å¿æäº¤ PRã</p><hr><h2 id="napcat-æ¬å°é¨ç½²" tabindex="-1"><a class="header-anchor" href="#napcat-æ¬å°é¨ç½²"><span>NapCat æ¬å°é¨ç½²</span></a></h2><p>NcatBot ä¾èµ <a href="https://github.com/NapNeko/NapCatQQ" target="_blank" rel="noopener noreferrer">NapCat</a> ä½ä¸º OneBot v11 åè®®å端ãé¡¹ç®æ ¹ç®å½ç <code>napcat/</code> å å«é¢é ç½®ç NapCat æä»¶ã</p><h3 id="å¯å¨-napcat" tabindex="-1"><a class="header-anchor" href="#å¯å¨-napcat"><span>å¯å¨ NapCat</span></a></h3><div class="language-powershell line-numbers-mode" data-ext="powershell" data-title="powershell"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># Windows â 使ç¨å¿«éç»å½èæ¬</span></span> 101<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">
101.\\napcat\\</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">1550507358_quickLogin.bat</span></span> 102<span class="line"></span> 103<span class="line"><span style="--shiki-light:#A0ADA0;--shiki-dark:#758575DD;"># æä½¿ç¨éç¨å¯å¨èæ¬</span></span> 104<span class="line"><span style="--shiki-light:#393A34;--shiki-dark:#DBD7CAEE;">.\\napcat\\</span><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">launcher.bat</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="é ç½®æä»¶" tabindex="-1"><a class="header-anchor" href="#é ç½®æä»¶"><span>é ç½®æä»¶</span></a></h3><p>NapCat é ç½®æä»¶ä½äº <code>napcat/config/</code> ç®å½ï¼å ³é®é 置项ï¼</p><table><thead><tr><th>æä»¶</th><th>说æ</th></tr></thead><tbody><tr><td><code>napcat/qqnt.json</code></td><td>QQ çæ¬ä¸åè®®é ç½®</td></tr><tr><td><code>napcat/config/</code></td><td>WebSocket / HTTP è¿æ¥é ç½®</td></tr></tbody></table><h3 id="è¿æ¥-ncatbot" tabindex="-1"><a class="header-anchor" href="#è¿æ¥-ncatbot"><span>è¿æ¥ NcatBot</span></a></h3><p>ç¡®ä¿ NapCat ä¸ NcatBot ç WebSocket 端å£ä¸è´ï¼é»è®¤ <code>3001</code>ï¼ï¼å¨é¡¹ç®ç <code>config.yaml</code> ä¸é ç½®ï¼</p><div class="language-yaml line-numbers-mode" data-ext="yaml" data-title="yaml"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">ws_port</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91;"> 3001</span></span> 105<span class="line"><span style="--shiki-light:#998418;--shiki-dark:#B8A965;">http_port</span><span style="--shiki-light:#999999;--shiki-dark:#666666;">:</span><span style="--shiki-light:#2F798A;--shiki-dark:#4C9A91;"> 3000</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div></div></div><blockquote><p>å¼åç¯å¢å¯ä½¿ç¨ <code>dev/config.yaml</code> è¦çé»è®¤é ç½®ã</p></blockquote><hr><h2 id="常è§é®é¢ææ¥" tabindex="-1"><a class="header-anchor" href="#常è§é®é¢ææ¥"><span>常è§é®é¢ææ¥</span></a></h2><h3 id="uv-sync-å®è£ 失败" tabindex="-1"><a class="header-anchor" href="#uv-sync-å®è£ 失败"><span><code>uv sync</code> å®è£ 失败</span></a></h3><ul><li><strong>æ£æ¥ Python çæ¬</strong>ï¼<code>python --version</code> 确认 ⥠3.12</li><li><strong>æ£æ¥ uv çæ¬</strong>ï¼<code>uv --version</code>ï¼å»ºè®®åçº§å°ææ°ï¼<code>uv self update</code></li><li><strong>ç½ç»é®é¢</strong>ï¼é ç½®éåæº</li></ul><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> sync</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --extra</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> dev</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --index-url</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> https://pypi.tuna.tsinghua.edu.cn/simple</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div></div></div><h3 id="import-ncatbot-æ¥é-modulenotfounderror" tabindex="-1"><a class="header-anchor" href="#import-ncatbot-æ¥é-modulenotfounderror"><span><code>import ncatbot</code> æ¥é ModuleNotFoundError</span></a></h3><ul><li><strong>æªæ¿æ´»èæç¯å¢</strong>ï¼æ§è¡ <code>.venv\\Scripts\\activate.ps1</code>ï¼Windowsï¼æ <code>source .venv/bin/activate</code>ï¼Linux/macOSï¼</li><li><strong>ä¾èµæªå®è£ </strong>ï¼æ§è¡ <code>uv sync --extra dev</code></li><li><strong>IDE è§£é卿ªæå <code>.venv</code></strong>ï¼å¨ VSCode 䏿 <code>Ctrl+Shift+P</code> â "Python: Select Interpreter" â éæ© <code>.venv</code> ä¸ç Python</li></ul><h3 id="pre-commit-æ¥é" tabindex="-1"><a class="header-anchor" href="#pre-commit-æ¥é"><span>pre-commit æ¥é</span></a></h3><ul><li><strong>馿¬¡è¿è¡æ ¢</strong>
105ï¼pre-commit éè¦ä¸è½½é©åç¯å¢ï¼å±æ£å¸¸ç°è±¡</li><li><strong>èªå¨ä¿®å¤åæäº¤å¤±è´¥</strong>ï¼è¿æ¯é¢æè¡ä¸ºï¼<code>git add .</code> åéæ° <code>git commit</code></li><li><strong>æ¸ é¤ç¼åéè£ </strong>ï¼</li></ul><div class="language-bash line-numbers-mode" data-ext="bash" data-title="bash"><button class="copy" title="å¤å¶ä»£ç " data-copied="å·²å¤å¶"></button><pre class="shiki shiki-themes vitesse-light vitesse-dark vp-code"><code><span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pre-commit</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> clean</span></span> 106<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pre-commit</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> install</span></span> 107<span class="line"><span style="--shiki-light:#59873A;--shiki-dark:#80A665;">uv</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> pre-commit</span><span style="--shiki-light:#B56959;--shiki-dark:#C98A7D;"> run</span><span style="--shiki-light:#A65E2B;--shiki-dark:#C99076;"> --all-files</span></span></code></pre><div class="line-numbers" aria-hidden="true" style="counter-reset:line-number 0;"><div class="line-number"></div><div class="line-number"></div><div class="line-number"></div></div></div><h3 id="pytest-æ¾ä¸å°æµè¯" tabindex="-1"><a class="header-anchor" href="#pytest-æ¾ä¸å°æµè¯"><span>pytest æ¾ä¸å°æµè¯</span></a></h3><ul><li><strong>确认å¨é¡¹ç®æ ¹ç®å½æ§è¡</strong>ï¼<code>cd ncatbot</code> é¡¹ç®æ ¹ç®å½</li><li><strong>确认èæç¯å¢å·²æ¿æ´»</strong></li><li><strong>æ¥ç pytest é ç½®</strong>ï¼<code>pyproject.toml</code> ä¸ <code>[tool.pytest.ini_options]</code> ç <code>testpaths</code> 设置</li></ul><h3 id="napcat-è¿æ¥å¤±è´¥" tabindex="-1"><a class="header-anchor" href="#napcat-è¿æ¥å¤±è´¥"><span>NapCat è¿æ¥å¤±è´¥</span></a></h3><ul><li><strong>确认 NapCat å·²å¯å¨</strong>ï¼æ£æ¥ NapCat ç»ç«¯æ¯å¦æé误è¾åº</li><li><strong>端å£å²çª</strong>ï¼ç¡®è®¤ <code>ws_port</code>ï¼é»è®¤ 3001ï¼å <code>http_port</code>ï¼é»è®¤ 3000ï¼æªè¢«å ç¨</li><li><strong>é²ç«å¢</strong>ï¼ç¡®ä¿æ¬å°é²ç«å¢æªæ¦æª WebSocket è¿æ¥</li></ul><h3 id="tox-ä¸è½½-python-失败" tabindex="-1"><a class="header-anchor" href="#tox-ä¸è½½-python-失败"><span>tox ä¸è½½ Python 失败</span></a></h3><ul><li><strong>ç½ç»é®é¢</strong>ï¼tox-uv ä¼èªå¨ä¸è½½ Pythonï¼ç¡®ä¿ç½ç»ç é</li><li><strong>è·³è¿å¤çæ¬æµè¯</strong>ï¼å¤çæ¬æµè¯éå¿ éï¼CI ä¼èªå¨å¤çï¼æ¬å°åªé <code>uv run pytest</code> å³å¯</li></ul>`,67)]))}const k=i(l,[["render",h],["__file","index.html.vue"]]),d=JSON.parse('{"path":"/contributing/p7czpap8/","title":"é«çº§å¼åç¯å¢","lang":"zh-CN","frontmatter":{"title":"é«çº§å¼åç¯å¢","createTime":"2026/03/19 17:26:45","permalink":"/contributing/p7czpap8/","description":"IDE é ç½®ãè°è¯æå·§ãCI/CD æ¬å°æ¨¡æãNapCat æ¬å°é¨ç½²ä¸å¸¸è§é®é¢ææ¥ã ç®å½ IDE é ç½®ï¼VSCodeï¼ è°è¯é ç½® pre-commit 详解 CI/CD æ¬å°æ¨¡æ NapCat æ¬å°é¨ç½² 常è§é®é¢ææ¥ IDE é ç½®ï¼VSCodeï¼ æ¨èæ©å± å¨ VSCode ä¸å®è£ 以䏿©å±ä»¥è·å¾æä½³å¼åä½éªï¼ æ¨è settings.json å¨é¡¹ç®...","head":[["meta",{"property":"og:url","content":"http://docs.ncatbot.xyz/contributing/p7czpap8/"}],["meta",{"property":"og:site_name","content":"NcatBot ææ¡£"}],["meta",{"property":"og:title","content":"é«çº§å¼åç¯å¢"}],["meta",{"property":"og:description","content":"IDE é ç½®ãè°è¯æå·§ãCI/CD æ¬å°æ¨¡æãNapCat æ¬å°é¨ç½²ä¸å¸¸è§é®é¢ææ¥ã ç®å½ IDE é ç½®ï¼VSCodeï¼ è°è¯é ç½® pre-commit 详解 CI/CD æ¬å°æ¨¡æ NapCat æ¬å°é¨ç½² 常è§é®é¢ææ¥ IDE é ç½®ï¼VSCodeï¼ æ¨èæ©å± å¨ VSCode ä¸å®è£ 以䏿©å±ä»¥è·å¾æä½³å¼åä½éªï¼ æ¨è settings.json å¨é¡¹ç®..."}],["meta",{"property":"og:type","content":"article"}],["meta",{"property":"og:locale","content":"zh-CN"}
107],["meta",{"property":"og:updated_time","content":"2026-04-30T14:41:02.000Z"}],["meta",{"property":"article:modified_time","content":"2026-04-30T14:41:02.000Z"}],["script",{"type":"application/ld+json"},"{\\"@context\\":\\"https://schema.org\\",\\"@type\\":\\"Article\\",\\"headline\\":\\"é«çº§å¼åç¯å¢\\",\\"image\\":[\\"\\"],\\"dateModified\\":\\"2026-04-30T14:41:02.000Z\\",\\"author\\":[]}"]]},"headers":[],"readingTime":{"minutes":4.26,"words":1279},"git":{"updatedTime":1777560062000,"contributors":[{"name":"GEYUANwuqi","username":"GEYUANwuqi","email":"[email protected]","commits":1,"avatar":"https://gravatar.com/avatar/1cf26d82e91dff657f3fa4d4911cdabcf7b76396339e886e69f99b15d4c8c808?d=retro"}]},"autoDesc":true,"filePathRelative":"notes/contributing/1. å¼åç¯å¢/1. é«çº§è®¾ç½®.md"}');export{k as comp,d as data};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.