ccjk 14.2.2 → 15.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -1
- package/README.md +58 -341
- package/dist/cli.js +59 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/detect.js +15 -0
- package/dist/commands/detect.js.map +1 -0
- package/dist/commands/doctor.js +68 -0
- package/dist/commands/doctor.js.map +1 -0
- package/dist/commands/git-install.js +50 -0
- package/dist/commands/git-install.js.map +1 -0
- package/dist/commands/init.js +102 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/mcp.js +66 -0
- package/dist/commands/mcp.js.map +1 -0
- package/dist/commands/menu.js +33 -0
- package/dist/commands/menu.js.map +1 -0
- package/dist/core/detect.js +24 -0
- package/dist/core/detect.js.map +1 -0
- package/dist/core/lint.js +49 -0
- package/dist/core/lint.js.map +1 -0
- package/dist/core/mcp.js +41 -0
- package/dist/core/mcp.js.map +1 -0
- package/dist/core/paths.js +9 -0
- package/dist/core/paths.js.map +1 -0
- package/dist/core/providers.js +53 -0
- package/dist/core/providers.js.map +1 -0
- package/dist/core/settings.js +31 -0
- package/dist/core/settings.js.map +1 -0
- package/dist/core/slash-templates.js +56 -0
- package/dist/core/slash-templates.js.map +1 -0
- package/dist/core/tools.js +27 -0
- package/dist/core/tools.js.map +1 -0
- package/package.json +43 -164
- package/README.HONEST.md +0 -176
- package/README.en.md +0 -67
- package/README.ja.md +0 -67
- package/README.ko.md +0 -67
- package/README.zh-CN.md +0 -86
- package/bin/ccjk.mjs +0 -5
- package/bin/ccjk.ts +0 -222
- package/dist/chunks/agent-teams.mjs +0 -145
- package/dist/chunks/agent.mjs +0 -1439
- package/dist/chunks/agents.mjs +0 -3783
- package/dist/chunks/api-cli.mjs +0 -135
- package/dist/chunks/api-config-selector.mjs +0 -159
- package/dist/chunks/api-providers.mjs +0 -144
- package/dist/chunks/api.mjs +0 -115
- package/dist/chunks/auto-bootstrap.mjs +0 -358
- package/dist/chunks/auto-fixer.mjs +0 -95
- package/dist/chunks/auto-updater.mjs +0 -507
- package/dist/chunks/banner.mjs +0 -173
- package/dist/chunks/bash.mjs +0 -187
- package/dist/chunks/boost.mjs +0 -474
- package/dist/chunks/brain-config.mjs +0 -75
- package/dist/chunks/brain-status.mjs +0 -89
- package/dist/chunks/ccjk-agents.mjs +0 -416
- package/dist/chunks/ccjk-all.mjs +0 -1046
- package/dist/chunks/ccjk-config.mjs +0 -445
- package/dist/chunks/ccjk-hooks.mjs +0 -1074
- package/dist/chunks/ccjk-mcp.mjs +0 -763
- package/dist/chunks/ccjk-setup.mjs +0 -765
- package/dist/chunks/ccjk-skills.mjs +0 -518
- package/dist/chunks/ccr.mjs +0 -109
- package/dist/chunks/ccu.mjs +0 -40
- package/dist/chunks/check-updates.mjs +0 -117
- package/dist/chunks/claude-code-incremental-manager.mjs +0 -761
- package/dist/chunks/claude-config.mjs +0 -606
- package/dist/chunks/claude-config2.mjs +0 -62
- package/dist/chunks/claude-wrapper.mjs +0 -85
- package/dist/chunks/clavue-config.mjs +0 -1454
- package/dist/chunks/cleanup-migration.mjs +0 -20
- package/dist/chunks/cli-hook.mjs +0 -4096
- package/dist/chunks/cloud-sync.mjs +0 -29
- package/dist/chunks/code-type-resolver.mjs +0 -880
- package/dist/chunks/codex-config-switch.mjs +0 -452
- package/dist/chunks/codex-provider-manager.mjs +0 -238
- package/dist/chunks/codex-uninstaller.mjs +0 -404
- package/dist/chunks/codex.mjs +0 -2141
- package/dist/chunks/commands.mjs +0 -108
- package/dist/chunks/commands2.mjs +0 -421
- package/dist/chunks/commit.mjs +0 -140
- package/dist/chunks/completion.mjs +0 -517
- package/dist/chunks/config-consolidator.mjs +0 -172
- package/dist/chunks/config-switch.mjs +0 -334
- package/dist/chunks/config.mjs +0 -558
- package/dist/chunks/config2.mjs +0 -484
- package/dist/chunks/config3.mjs +0 -486
- package/dist/chunks/constants.mjs +0 -323
- package/dist/chunks/context-opt.mjs +0 -444
- package/dist/chunks/context.mjs +0 -974
- package/dist/chunks/dashboard.mjs +0 -481
- package/dist/chunks/doctor.mjs +0 -1301
- package/dist/chunks/eval.mjs +0 -502
- package/dist/chunks/evolution.mjs +0 -322
- package/dist/chunks/features.mjs +0 -715
- package/dist/chunks/fish.mjs +0 -181
- package/dist/chunks/fs-operations.mjs +0 -180
- package/dist/chunks/health-alerts.mjs +0 -830
- package/dist/chunks/help.mjs +0 -341
- package/dist/chunks/hook-installer.mjs +0 -48
- package/dist/chunks/impact.mjs +0 -651
- package/dist/chunks/index.mjs +0 -23
- package/dist/chunks/index10.mjs +0 -19
- package/dist/chunks/index11.mjs +0 -1171
- package/dist/chunks/index12.mjs +0 -218
- package/dist/chunks/index13.mjs +0 -679
- package/dist/chunks/index14.mjs +0 -1009
- package/dist/chunks/index15.mjs +0 -194
- package/dist/chunks/index2.mjs +0 -7637
- package/dist/chunks/index3.mjs +0 -171
- package/dist/chunks/index4.mjs +0 -26
- package/dist/chunks/index5.mjs +0 -19
- package/dist/chunks/index6.mjs +0 -19092
- package/dist/chunks/index7.mjs +0 -616
- package/dist/chunks/index8.mjs +0 -1602
- package/dist/chunks/index9.mjs +0 -5384
- package/dist/chunks/init.mjs +0 -1911
- package/dist/chunks/installer.mjs +0 -757
- package/dist/chunks/installer2.mjs +0 -103
- package/dist/chunks/interview.mjs +0 -2927
- package/dist/chunks/json-config.mjs +0 -60
- package/dist/chunks/linux.mjs +0 -3863
- package/dist/chunks/macos.mjs +0 -69
- package/dist/chunks/main.mjs +0 -635
- package/dist/chunks/manager.mjs +0 -1048
- package/dist/chunks/marketplace.mjs +0 -265
- package/dist/chunks/mcp-cli.mjs +0 -205
- package/dist/chunks/mcp-performance.mjs +0 -187
- package/dist/chunks/mcp.mjs +0 -667
- package/dist/chunks/memory-check.mjs +0 -2973
- package/dist/chunks/memory-paths.mjs +0 -259
- package/dist/chunks/memory-sync.mjs +0 -209
- package/dist/chunks/memory.mjs +0 -354
- package/dist/chunks/metrics-display.mjs +0 -153
- package/dist/chunks/monitor.mjs +0 -1856
- package/dist/chunks/notification.mjs +0 -1864
- package/dist/chunks/onboarding.mjs +0 -386
- package/dist/chunks/package.mjs +0 -3
- package/dist/chunks/paradigm.mjs +0 -74
- package/dist/chunks/permission-manager.mjs +0 -250
- package/dist/chunks/permissions.mjs +0 -265
- package/dist/chunks/persistence-manager.mjs +0 -801
- package/dist/chunks/persistence.mjs +0 -707
- package/dist/chunks/platform.mjs +0 -395
- package/dist/chunks/plugin.mjs +0 -1936
- package/dist/chunks/powershell.mjs +0 -213
- package/dist/chunks/prompts.mjs +0 -244
- package/dist/chunks/providers.mjs +0 -263
- package/dist/chunks/quick-actions.mjs +0 -335
- package/dist/chunks/quick-provider.mjs +0 -755
- package/dist/chunks/quick-setup.mjs +0 -421
- package/dist/chunks/remote.mjs +0 -497
- package/dist/chunks/research.mjs +0 -1904
- package/dist/chunks/rollback.mjs +0 -38
- package/dist/chunks/session-manager.mjs +0 -1371
- package/dist/chunks/session.mjs +0 -878
- package/dist/chunks/sessions.mjs +0 -106
- package/dist/chunks/silent-updater.mjs +0 -396
- package/dist/chunks/simple-config.mjs +0 -122
- package/dist/chunks/skill.mjs +0 -117
- package/dist/chunks/skill2.mjs +0 -9052
- package/dist/chunks/skills-sync.mjs +0 -1343
- package/dist/chunks/skills.mjs +0 -577
- package/dist/chunks/slash-commands.mjs +0 -208
- package/dist/chunks/smart-guide.mjs +0 -247
- package/dist/chunks/snapshot.mjs +0 -58
- package/dist/chunks/startup.mjs +0 -487
- package/dist/chunks/stats.mjs +0 -191
- package/dist/chunks/status.mjs +0 -471
- package/dist/chunks/team.mjs +0 -63
- package/dist/chunks/thinking.mjs +0 -626
- package/dist/chunks/trace.mjs +0 -57
- package/dist/chunks/uninstall.mjs +0 -852
- package/dist/chunks/update.mjs +0 -174
- package/dist/chunks/upgrade-manager.mjs +0 -204
- package/dist/chunks/upgrade.mjs +0 -133
- package/dist/chunks/version-checker.mjs +0 -891
- package/dist/chunks/vim.mjs +0 -903
- package/dist/chunks/windows.mjs +0 -14
- package/dist/chunks/workflows.mjs +0 -633
- package/dist/chunks/wsl.mjs +0 -129
- package/dist/chunks/zero-config.mjs +0 -871
- package/dist/chunks/zsh.mjs +0 -182
- package/dist/cli.d.mts +0 -1
- package/dist/cli.d.ts +0 -1
- package/dist/cli.mjs +0 -2684
- package/dist/i18n/locales/en/agent-teams.json +0 -18
- package/dist/i18n/locales/en/agentBrowser.json +0 -80
- package/dist/i18n/locales/en/agents.json +0 -135
- package/dist/i18n/locales/en/api.json +0 -63
- package/dist/i18n/locales/en/ccjk-agents.json +0 -33
- package/dist/i18n/locales/en/ccjk-all.json +0 -23
- package/dist/i18n/locales/en/ccjk-skills.json +0 -22
- package/dist/i18n/locales/en/ccjk.json +0 -276
- package/dist/i18n/locales/en/ccr.json +0 -65
- package/dist/i18n/locales/en/claude-md.json +0 -73
- package/dist/i18n/locales/en/cli.json +0 -148
- package/dist/i18n/locales/en/cloud-setup.json +0 -31
- package/dist/i18n/locales/en/cloud-sync.json +0 -147
- package/dist/i18n/locales/en/cloud.json +0 -40
- package/dist/i18n/locales/en/cloudPlugins.json +0 -118
- package/dist/i18n/locales/en/codex.json +0 -184
- package/dist/i18n/locales/en/cometix.json +0 -29
- package/dist/i18n/locales/en/common.json +0 -68
- package/dist/i18n/locales/en/config.json +0 -108
- package/dist/i18n/locales/en/configuration.json +0 -236
- package/dist/i18n/locales/en/context.json +0 -85
- package/dist/i18n/locales/en/dashboard.json +0 -78
- package/dist/i18n/locales/en/errors.json +0 -26
- package/dist/i18n/locales/en/evolution.json +0 -54
- package/dist/i18n/locales/en/hooks.json +0 -74
- package/dist/i18n/locales/en/hooksSync.json +0 -133
- package/dist/i18n/locales/en/installation.json +0 -83
- package/dist/i18n/locales/en/interview.json +0 -104
- package/dist/i18n/locales/en/language.json +0 -19
- package/dist/i18n/locales/en/lsp.json +0 -78
- package/dist/i18n/locales/en/marketplace.json +0 -116
- package/dist/i18n/locales/en/mcp.json +0 -180
- package/dist/i18n/locales/en/memory.json +0 -23
- package/dist/i18n/locales/en/menu.json +0 -299
- package/dist/i18n/locales/en/multi-config.json +0 -79
- package/dist/i18n/locales/en/notification.json +0 -307
- package/dist/i18n/locales/en/permissions.json +0 -95
- package/dist/i18n/locales/en/persistence.json +0 -127
- package/dist/i18n/locales/en/plugins.json +0 -146
- package/dist/i18n/locales/en/quick-actions.json +0 -78
- package/dist/i18n/locales/en/registry.json +0 -54
- package/dist/i18n/locales/en/remote.json +0 -93
- package/dist/i18n/locales/en/sandbox.json +0 -44
- package/dist/i18n/locales/en/setup.json +0 -44
- package/dist/i18n/locales/en/shencha.json +0 -14
- package/dist/i18n/locales/en/skills.json +0 -100
- package/dist/i18n/locales/en/skillsSync.json +0 -74
- package/dist/i18n/locales/en/smartGuide.json +0 -49
- package/dist/i18n/locales/en/stats.json +0 -20
- package/dist/i18n/locales/en/subagent.json +0 -69
- package/dist/i18n/locales/en/superpowers.json +0 -117
- package/dist/i18n/locales/en/team.json +0 -7
- package/dist/i18n/locales/en/thinking.json +0 -65
- package/dist/i18n/locales/en/tools.json +0 -42
- package/dist/i18n/locales/en/uninstall.json +0 -56
- package/dist/i18n/locales/en/updater.json +0 -29
- package/dist/i18n/locales/en/vim.json +0 -169
- package/dist/i18n/locales/en/workflow.json +0 -55
- package/dist/i18n/locales/en/workspace.json +0 -108
- package/dist/i18n/locales/zh-CN/agent-teams.json +0 -18
- package/dist/i18n/locales/zh-CN/agentBrowser.json +0 -80
- package/dist/i18n/locales/zh-CN/agents.json +0 -135
- package/dist/i18n/locales/zh-CN/api.json +0 -63
- package/dist/i18n/locales/zh-CN/ccjk-agents.json +0 -33
- package/dist/i18n/locales/zh-CN/ccjk-all.json +0 -23
- package/dist/i18n/locales/zh-CN/ccjk-skills.json +0 -22
- package/dist/i18n/locales/zh-CN/ccjk.json +0 -276
- package/dist/i18n/locales/zh-CN/ccr.json +0 -65
- package/dist/i18n/locales/zh-CN/claude-md.json +0 -73
- package/dist/i18n/locales/zh-CN/cli.json +0 -148
- package/dist/i18n/locales/zh-CN/cloud-setup.json +0 -31
- package/dist/i18n/locales/zh-CN/cloud-sync.json +0 -147
- package/dist/i18n/locales/zh-CN/cloud.json +0 -40
- package/dist/i18n/locales/zh-CN/cloudPlugins.json +0 -118
- package/dist/i18n/locales/zh-CN/codex.json +0 -184
- package/dist/i18n/locales/zh-CN/cometix.json +0 -29
- package/dist/i18n/locales/zh-CN/common.json +0 -68
- package/dist/i18n/locales/zh-CN/config.json +0 -108
- package/dist/i18n/locales/zh-CN/configuration.json +0 -234
- package/dist/i18n/locales/zh-CN/context.json +0 -85
- package/dist/i18n/locales/zh-CN/dashboard.json +0 -78
- package/dist/i18n/locales/zh-CN/errors.json +0 -26
- package/dist/i18n/locales/zh-CN/evolution.json +0 -54
- package/dist/i18n/locales/zh-CN/hooks.json +0 -74
- package/dist/i18n/locales/zh-CN/hooksSync.json +0 -133
- package/dist/i18n/locales/zh-CN/installation.json +0 -83
- package/dist/i18n/locales/zh-CN/interview.json +0 -104
- package/dist/i18n/locales/zh-CN/language.json +0 -19
- package/dist/i18n/locales/zh-CN/lsp.json +0 -78
- package/dist/i18n/locales/zh-CN/marketplace.json +0 -116
- package/dist/i18n/locales/zh-CN/mcp.json +0 -180
- package/dist/i18n/locales/zh-CN/memory.json +0 -23
- package/dist/i18n/locales/zh-CN/menu.json +0 -299
- package/dist/i18n/locales/zh-CN/multi-config.json +0 -79
- package/dist/i18n/locales/zh-CN/notification.json +0 -307
- package/dist/i18n/locales/zh-CN/permissions.json +0 -95
- package/dist/i18n/locales/zh-CN/persistence.json +0 -127
- package/dist/i18n/locales/zh-CN/plugins.json +0 -146
- package/dist/i18n/locales/zh-CN/quick-actions.json +0 -78
- package/dist/i18n/locales/zh-CN/registry.json +0 -54
- package/dist/i18n/locales/zh-CN/remote.json +0 -93
- package/dist/i18n/locales/zh-CN/sandbox.json +0 -44
- package/dist/i18n/locales/zh-CN/setup.json +0 -44
- package/dist/i18n/locales/zh-CN/shencha.json +0 -14
- package/dist/i18n/locales/zh-CN/skills.json +0 -100
- package/dist/i18n/locales/zh-CN/skillsSync.json +0 -74
- package/dist/i18n/locales/zh-CN/smartGuide.json +0 -49
- package/dist/i18n/locales/zh-CN/stats.json +0 -20
- package/dist/i18n/locales/zh-CN/subagent.json +0 -69
- package/dist/i18n/locales/zh-CN/superpowers.json +0 -117
- package/dist/i18n/locales/zh-CN/team.json +0 -7
- package/dist/i18n/locales/zh-CN/thinking.json +0 -65
- package/dist/i18n/locales/zh-CN/tools.json +0 -42
- package/dist/i18n/locales/zh-CN/uninstall.json +0 -56
- package/dist/i18n/locales/zh-CN/updater.json +0 -29
- package/dist/i18n/locales/zh-CN/vim.json +0 -169
- package/dist/i18n/locales/zh-CN/workflow.json +0 -55
- package/dist/i18n/locales/zh-CN/workspace.json +0 -108
- package/dist/index.d.mts +0 -5658
- package/dist/index.d.ts +0 -5658
- package/dist/index.mjs +0 -3732
- package/dist/shared/ccjk.5bEolFrk.mjs +0 -254
- package/dist/shared/ccjk.8oaxX4iR.mjs +0 -90
- package/dist/shared/ccjk.B2U7DsPy.mjs +0 -31
- package/dist/shared/ccjk.B2f-cwUP.mjs +0 -468
- package/dist/shared/ccjk.BAGoDD49.mjs +0 -36
- package/dist/shared/ccjk.BBtCGd_g.mjs +0 -899
- package/dist/shared/ccjk.BFQ7yr5S.mjs +0 -16
- package/dist/shared/ccjk.BLsIiTqO.mjs +0 -449
- package/dist/shared/ccjk.BXv8aYs1.mjs +0 -170
- package/dist/shared/ccjk.BnsY5WxD.mjs +0 -171
- package/dist/shared/ccjk.BoApaI4j.mjs +0 -28
- package/dist/shared/ccjk.Bq8TqZG_.mjs +0 -189
- package/dist/shared/ccjk.BtrioX1Z.mjs +0 -25
- package/dist/shared/ccjk.Bx_rmYfN.mjs +0 -69
- package/dist/shared/ccjk.BzPbSEP2.mjs +0 -115
- package/dist/shared/ccjk.C0WLUnFV.mjs +0 -293
- package/dist/shared/ccjk.C1hANZTu.mjs +0 -19
- package/dist/shared/ccjk.C2jHOZVP.mjs +0 -52
- package/dist/shared/ccjk.CNhnT6uQ.mjs +0 -636
- package/dist/shared/ccjk.COweQ1RR.mjs +0 -5
- package/dist/shared/ccjk.CfKKcvWy.mjs +0 -126
- package/dist/shared/ccjk.Cjgrln_h.mjs +0 -297
- package/dist/shared/ccjk.CoCHVXl3.mjs +0 -3951
- package/dist/shared/ccjk.CwGZSTAK.mjs +0 -319
- package/dist/shared/ccjk.CxpGa6MC.mjs +0 -2724
- package/dist/shared/ccjk.D-magaEx.mjs +0 -763
- package/dist/shared/ccjk.D0g2ABGg.mjs +0 -171
- package/dist/shared/ccjk.D6ycHbak.mjs +0 -270
- package/dist/shared/ccjk.D75wivnp.mjs +0 -142
- package/dist/shared/ccjk.DDL-4C-k.mjs +0 -100
- package/dist/shared/ccjk.DFRPtmK_.mjs +0 -75
- package/dist/shared/ccjk.DMV3x5Sd.mjs +0 -299
- package/dist/shared/ccjk.DZ2LLOa-.mjs +0 -2195
- package/dist/shared/ccjk.DbigonEQ.mjs +0 -698
- package/dist/shared/ccjk.DcMvE7lf.mjs +0 -618
- package/dist/shared/ccjk.DeWpAShp.mjs +0 -1828
- package/dist/shared/ccjk.DhJ1kyDR.mjs +0 -30
- package/dist/shared/ccjk.DlTXS9rP.mjs +0 -224
- package/dist/shared/ccjk.DopKzo3z.mjs +0 -305
- package/dist/shared/ccjk.DsZsc4LR.mjs +0 -1280
- package/dist/shared/ccjk.DuzJZlgj.mjs +0 -418
- package/dist/shared/ccjk.Dxgd2vjc.mjs +0 -444
- package/dist/shared/ccjk.J8YiPsOw.mjs +0 -259
- package/dist/shared/ccjk.KfSWcGlE.mjs +0 -38
- package/dist/shared/ccjk.L7yC58_i.mjs +0 -225
- package/dist/shared/ccjk.MwtjAULc.mjs +0 -1447
- package/dist/shared/ccjk.OJKHVSOb.mjs +0 -2005
- package/dist/shared/ccjk.OTnevPNE.mjs +0 -225
- package/dist/shared/ccjk.RyizuzOI.mjs +0 -21
- package/dist/shared/ccjk.T_cX87dY.mjs +0 -15
- package/dist/shared/ccjk.bQ7Dh1g4.mjs +0 -249
- package/dist/shared/ccjk.gDEDGD_t.mjs +0 -38
- package/dist/shared/ccjk.hoqrwWdN.mjs +0 -333
- package/dist/shared/ccjk.i_vn-9C3.mjs +0 -317
- package/dist/shared/ccjk.lG3ccFjm.mjs +0 -885
- package/dist/shared/ccjk.wLJHO0Af.mjs +0 -244
- package/dist/shared/ccjk.y-a_1vK4.mjs +0 -5127
- package/dist/templates/agents/README.md +0 -78
- package/dist/templates/agents/fullstack-developer.json +0 -70
- package/dist/templates/agents/go-expert.json +0 -69
- package/dist/templates/agents/index.json +0 -64
- package/dist/templates/agents/python-expert.json +0 -69
- package/dist/templates/agents/react-specialist.json +0 -69
- package/dist/templates/agents/testing-automation-expert.json +0 -70
- package/dist/templates/agents/typescript-architect.json +0 -69
- package/dist/templates/claude-code/common/settings.json +0 -109
- package/dist/templates/common/error-prevention.md +0 -267
- package/dist/templates/common/karpathy-baseline.md +0 -83
- package/dist/templates/common/output-styles/zh-CN/carmack-mode.md +0 -381
- package/dist/templates/common/output-styles/zh-CN/codex-rigor-mode.md +0 -114
- package/dist/templates/common/output-styles/zh-CN/dhh-mode.md +0 -265
- package/dist/templates/common/output-styles/zh-CN/evan-you-mode.md +0 -539
- package/dist/templates/common/output-styles/zh-CN/jobs-mode.md +0 -369
- package/dist/templates/common/output-styles/zh-CN/linus-mode.md +0 -135
- package/dist/templates/common/output-styles/zh-CN/uncle-bob-mode.md +0 -221
- package/dist/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +0 -628
- package/dist/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +0 -628
- package/dist/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +0 -187
- package/dist/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +0 -191
- package/dist/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +0 -249
- package/dist/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +0 -277
- package/dist/templates/common/workflow/essential/en/agents/get-current-datetime.md +0 -29
- package/dist/templates/common/workflow/essential/en/agents/init-architect.md +0 -115
- package/dist/templates/common/workflow/essential/en/agents/ui-ux-designer.md +0 -91
- package/dist/templates/common/workflow/essential/en/feat.md +0 -92
- package/dist/templates/common/workflow/essential/en/goal.md +0 -147
- package/dist/templates/common/workflow/essential/en/init-project.md +0 -53
- package/dist/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +0 -29
- package/dist/templates/common/workflow/essential/zh-CN/agents/init-architect.md +0 -115
- package/dist/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +0 -91
- package/dist/templates/common/workflow/essential/zh-CN/feat.md +0 -315
- package/dist/templates/common/workflow/essential/zh-CN/goal.md +0 -146
- package/dist/templates/common/workflow/essential/zh-CN/init-project.md +0 -53
- package/dist/templates/common/workflow/git/en/git-cleanBranches.md +0 -102
- package/dist/templates/common/workflow/git/en/git-commit.md +0 -205
- package/dist/templates/common/workflow/git/en/git-rollback.md +0 -90
- package/dist/templates/common/workflow/git/en/git-worktree.md +0 -276
- package/dist/templates/common/workflow/git/zh-CN/git-cleanBranches.md +0 -102
- package/dist/templates/common/workflow/git/zh-CN/git-commit.md +0 -205
- package/dist/templates/common/workflow/git/zh-CN/git-rollback.md +0 -90
- package/dist/templates/common/workflow/git/zh-CN/git-worktree.md +0 -276
- package/dist/templates/common/workflow/interview/en/interview.md +0 -67
- package/dist/templates/common/workflow/interview/zh-CN/interview.md +0 -67
- package/dist/templates/common/workflow/linearMethod/en/linear-method.md +0 -651
- package/dist/templates/common/workflow/linearMethod/zh-CN/linear-method.md +0 -752
- package/dist/templates/common/workflow/refactoringMaster/en/refactoring-master.md +0 -516
- package/dist/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +0 -812
- package/dist/templates/common/workflow/sixStep/en/workflow.md +0 -83
- package/dist/templates/common/workflow/sixStep/zh-CN/workflow.md +0 -359
- package/dist/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +0 -364
- package/dist/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +0 -366
- package/dist/templates/hooks/README.md +0 -212
- package/dist/templates/hooks/git-workflow-hooks.md +0 -551
- package/dist/templates/hooks/post-test/coverage.json +0 -21
- package/dist/templates/hooks/post-test/summary.json +0 -21
- package/dist/templates/hooks/post-test-coverage.md +0 -434
- package/dist/templates/hooks/pre-commit/eslint.json +0 -22
- package/dist/templates/hooks/pre-commit/prettier.json +0 -22
- package/dist/templates/hooks/pre-commit-black.md +0 -274
- package/dist/templates/hooks/pre-commit-eslint.md +0 -153
- package/dist/templates/hooks/pre-commit-gofmt.md +0 -284
- package/dist/templates/hooks/pre-commit-prettier.md +0 -212
- package/dist/templates/hooks/pre-commit-type-check.md +0 -377
- package/dist/templates/skills/ccjk-init.md +0 -154
- package/dist/templates/skills/ccjk-mcp-setup.md +0 -205
- package/dist/templates/skills/ccjk-troubleshoot.md +0 -228
- package/dist/templates/skills/django-patterns.md +0 -1016
- package/dist/templates/skills/git-workflow.md +0 -748
- package/dist/templates/skills/go-idioms.md +0 -963
- package/dist/templates/skills/index.json +0 -132
- package/dist/templates/skills/nextjs-optimization.md +0 -694
- package/dist/templates/skills/python-pep8.md +0 -852
- package/dist/templates/skills/react-patterns.md +0 -686
- package/dist/templates/skills/rust-patterns.md +0 -1057
- package/dist/templates/skills/security-best-practices.md +0 -1413
- package/dist/templates/skills/testing-best-practices.md +0 -1315
- package/dist/templates/skills/ts-best-practices.md +0 -354
- package/templates/agents/README.md +0 -78
- package/templates/agents/fullstack-developer.json +0 -70
- package/templates/agents/go-expert.json +0 -69
- package/templates/agents/index.json +0 -64
- package/templates/agents/python-expert.json +0 -69
- package/templates/agents/react-specialist.json +0 -69
- package/templates/agents/testing-automation-expert.json +0 -70
- package/templates/agents/typescript-architect.json +0 -69
- package/templates/claude-code/common/settings.json +0 -109
- package/templates/common/error-prevention.md +0 -267
- package/templates/common/karpathy-baseline.md +0 -83
- package/templates/common/output-styles/zh-CN/carmack-mode.md +0 -381
- package/templates/common/output-styles/zh-CN/codex-rigor-mode.md +0 -114
- package/templates/common/output-styles/zh-CN/dhh-mode.md +0 -265
- package/templates/common/output-styles/zh-CN/evan-you-mode.md +0 -539
- package/templates/common/output-styles/zh-CN/jobs-mode.md +0 -369
- package/templates/common/output-styles/zh-CN/linus-mode.md +0 -135
- package/templates/common/output-styles/zh-CN/uncle-bob-mode.md +0 -221
- package/templates/common/workflow/continuousDelivery/en/continuous-delivery.md +0 -628
- package/templates/common/workflow/continuousDelivery/zh-CN/continuous-delivery.md +0 -628
- package/templates/common/workflow/essential/en/agents/ccjk-config-agent.md +0 -187
- package/templates/common/workflow/essential/en/agents/ccjk-mcp-agent.md +0 -191
- package/templates/common/workflow/essential/en/agents/ccjk-skill-agent.md +0 -249
- package/templates/common/workflow/essential/en/agents/ccjk-workflow-agent.md +0 -277
- package/templates/common/workflow/essential/en/agents/get-current-datetime.md +0 -29
- package/templates/common/workflow/essential/en/agents/init-architect.md +0 -115
- package/templates/common/workflow/essential/en/agents/ui-ux-designer.md +0 -91
- package/templates/common/workflow/essential/en/feat.md +0 -92
- package/templates/common/workflow/essential/en/goal.md +0 -147
- package/templates/common/workflow/essential/en/init-project.md +0 -53
- package/templates/common/workflow/essential/zh-CN/agents/get-current-datetime.md +0 -29
- package/templates/common/workflow/essential/zh-CN/agents/init-architect.md +0 -115
- package/templates/common/workflow/essential/zh-CN/agents/ui-ux-designer.md +0 -91
- package/templates/common/workflow/essential/zh-CN/feat.md +0 -315
- package/templates/common/workflow/essential/zh-CN/goal.md +0 -146
- package/templates/common/workflow/essential/zh-CN/init-project.md +0 -53
- package/templates/common/workflow/git/en/git-cleanBranches.md +0 -102
- package/templates/common/workflow/git/en/git-commit.md +0 -205
- package/templates/common/workflow/git/en/git-rollback.md +0 -90
- package/templates/common/workflow/git/en/git-worktree.md +0 -276
- package/templates/common/workflow/git/zh-CN/git-cleanBranches.md +0 -102
- package/templates/common/workflow/git/zh-CN/git-commit.md +0 -205
- package/templates/common/workflow/git/zh-CN/git-rollback.md +0 -90
- package/templates/common/workflow/git/zh-CN/git-worktree.md +0 -276
- package/templates/common/workflow/interview/en/interview.md +0 -67
- package/templates/common/workflow/interview/zh-CN/interview.md +0 -67
- package/templates/common/workflow/linearMethod/en/linear-method.md +0 -651
- package/templates/common/workflow/linearMethod/zh-CN/linear-method.md +0 -752
- package/templates/common/workflow/refactoringMaster/en/refactoring-master.md +0 -516
- package/templates/common/workflow/refactoringMaster/zh-CN/refactoring-master.md +0 -812
- package/templates/common/workflow/sixStep/en/workflow.md +0 -83
- package/templates/common/workflow/sixStep/zh-CN/workflow.md +0 -359
- package/templates/common/workflow/specFirstTDD/en/spec-first-tdd.md +0 -364
- package/templates/common/workflow/specFirstTDD/zh-CN/spec-first-tdd.md +0 -366
- package/templates/hooks/README.md +0 -212
- package/templates/hooks/git-workflow-hooks.md +0 -551
- package/templates/hooks/post-test/coverage.json +0 -21
- package/templates/hooks/post-test/summary.json +0 -21
- package/templates/hooks/post-test-coverage.md +0 -434
- package/templates/hooks/pre-commit/eslint.json +0 -22
- package/templates/hooks/pre-commit/prettier.json +0 -22
- package/templates/hooks/pre-commit-black.md +0 -274
- package/templates/hooks/pre-commit-eslint.md +0 -153
- package/templates/hooks/pre-commit-gofmt.md +0 -284
- package/templates/hooks/pre-commit-prettier.md +0 -212
- package/templates/hooks/pre-commit-type-check.md +0 -377
- package/templates/skills/basic.hbs +0 -72
- package/templates/skills/ccjk-init.md +0 -154
- package/templates/skills/ccjk-mcp-setup.md +0 -205
- package/templates/skills/ccjk-troubleshoot.md +0 -228
- package/templates/skills/code-refactor.hbs +0 -133
- package/templates/skills/code-review.hbs +0 -141
- package/templates/skills/django-patterns.md +0 -1016
- package/templates/skills/git-workflow.md +0 -748
- package/templates/skills/go-idioms.md +0 -963
- package/templates/skills/index.json +0 -132
- package/templates/skills/nextjs-optimization.md +0 -694
- package/templates/skills/python-pep8.md +0 -852
- package/templates/skills/react-patterns.md +0 -686
- package/templates/skills/rust-patterns.md +0 -1057
- package/templates/skills/security-best-practices.md +0 -1413
- package/templates/skills/testing-best-practices.md +0 -1315
- package/templates/skills/ts-best-practices.md +0 -354
- package/templates/skills/type-fix.hbs +0 -132
|
@@ -1,963 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: go-idioms
|
|
3
|
-
description: Go language conventions, error handling patterns, and idiomatic Go code
|
|
4
|
-
description_zh: Go 语言约定、错误处理模式和惯用 Go 代码
|
|
5
|
-
version: 1.0.0
|
|
6
|
-
category: programming
|
|
7
|
-
triggers: ['/go-idioms', '/golang', '/go-patterns', '/go-best-practices']
|
|
8
|
-
use_when:
|
|
9
|
-
- Writing idiomatic Go code following community conventions
|
|
10
|
-
- Implementing proper error handling and interface design
|
|
11
|
-
- Optimizing Go performance and memory usage
|
|
12
|
-
- Code review for Go projects
|
|
13
|
-
use_when_zh:
|
|
14
|
-
- 编写遵循社区约定的惯用 Go 代码
|
|
15
|
-
- 实现适当的错误处理和接口设计
|
|
16
|
-
- 优化 Go 性能和内存使用
|
|
17
|
-
- Go 项目代码审查
|
|
18
|
-
auto_activate: true
|
|
19
|
-
priority: 8
|
|
20
|
-
agents: [go-expert, systems-programmer]
|
|
21
|
-
tags: [golang, idioms, error-handling, interfaces, performance]
|
|
22
|
-
---
|
|
23
|
-
|
|
24
|
-
# Go Idioms | Go 惯用法
|
|
25
|
-
|
|
26
|
-
## Context | 上下文
|
|
27
|
-
|
|
28
|
-
Use this skill when writing Go code that follows community conventions, implements proper error handling, and leverages Go's unique features like goroutines and interfaces effectively.
|
|
29
|
-
|
|
30
|
-
在编写遵循社区约定、实现适当错误处理并有效利用 Go 独特功能(如 goroutines 和接口)的 Go 代码时使用此技能。
|
|
31
|
-
|
|
32
|
-
## Go Conventions and Style | Go 约定和风格
|
|
33
|
-
|
|
34
|
-
### 1. Naming Conventions | 命名约定
|
|
35
|
-
|
|
36
|
-
```go
|
|
37
|
-
package main
|
|
38
|
-
|
|
39
|
-
import (
|
|
40
|
-
"context"
|
|
41
|
-
"fmt"
|
|
42
|
-
"log"
|
|
43
|
-
"net/http"
|
|
44
|
-
"time"
|
|
45
|
-
)
|
|
46
|
-
|
|
47
|
-
// ✅ Good: Proper Go naming conventions
|
|
48
|
-
|
|
49
|
-
// Constants: CamelCase for exported, camelCase for unexported
|
|
50
|
-
const (
|
|
51
|
-
MaxRetries = 3
|
|
52
|
-
defaultTimeout = 30 * time.Second
|
|
53
|
-
)
|
|
54
|
-
|
|
55
|
-
// Variables: CamelCase for exported, camelCase for unexported
|
|
56
|
-
var (
|
|
57
|
-
ErrNotFound = errors.New("not found")
|
|
58
|
-
logger = log.New(os.Stdout, "app: ", log.LstdFlags)
|
|
59
|
-
)
|
|
60
|
-
|
|
61
|
-
// Types: CamelCase for exported, camelCase for unexported
|
|
62
|
-
type UserService struct {
|
|
63
|
-
db Database
|
|
64
|
-
cache Cache
|
|
65
|
-
logger *log.Logger
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
type userRepository struct {
|
|
69
|
-
conn *sql.DB
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// Interfaces: Often end with -er suffix
|
|
73
|
-
type Reader interface {
|
|
74
|
-
Read([]byte) (int, error)
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
type UserFinder interface {
|
|
78
|
-
FindByID(ctx context.Context, id string) (*User, error)
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
// Functions: CamelCase for exported, camelCase for unexported
|
|
82
|
-
func NewUserService(db Database, cache Cache) *UserService {
|
|
83
|
-
return &UserService{
|
|
84
|
-
db: db,
|
|
85
|
-
cache: cache,
|
|
86
|
-
logger: log.New(os.Stdout, "user-service: ", log.LstdFlags),
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
func (s *UserService) CreateUser(ctx context.Context, user *User) error {
|
|
91
|
-
return s.createUser(ctx, user)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
func (s *UserService) createUser(ctx context.Context, user *User) error {
|
|
95
|
-
// Implementation
|
|
96
|
-
return nil
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// ❌ Bad: Non-idiomatic naming
|
|
100
|
-
type user_service struct{} // Should be userService
|
|
101
|
-
func Get_User() {} // Should be GetUser
|
|
102
|
-
const max_retries = 3 // Should be MaxRetries or maxRetries
|
|
103
|
-
```
|
|
104
|
-
|
|
105
|
-
### 2. Package Organization | 包组织
|
|
106
|
-
|
|
107
|
-
```go
|
|
108
|
-
// ✅ Good: Package structure and imports
|
|
109
|
-
|
|
110
|
-
// Package declaration - short, descriptive, lowercase
|
|
111
|
-
package userservice
|
|
112
|
-
|
|
113
|
-
import (
|
|
114
|
-
// Standard library first
|
|
115
|
-
"context"
|
|
116
|
-
"fmt"
|
|
117
|
-
"log"
|
|
118
|
-
"net/http"
|
|
119
|
-
"time"
|
|
120
|
-
|
|
121
|
-
// Third-party packages
|
|
122
|
-
"github.com/gorilla/mux"
|
|
123
|
-
"github.com/lib/pq"
|
|
124
|
-
|
|
125
|
-
// Local packages
|
|
126
|
-
"myapp/internal/database"
|
|
127
|
-
"myapp/internal/models"
|
|
128
|
-
)
|
|
129
|
-
|
|
130
|
-
// Package-level documentation
|
|
131
|
-
// Package userservice provides user management functionality.
|
|
132
|
-
// It handles user creation, authentication, and profile management.
|
|
133
|
-
|
|
134
|
-
// ✅ Good: Avoid package name stuttering
|
|
135
|
-
type Service struct { // Not UserService in userservice package
|
|
136
|
-
db Database
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
func New(db Database) *Service { // Not NewUserService
|
|
140
|
-
return &Service{db: db}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
func (s *Service) Create(ctx context.Context, user *User) error {
|
|
144
|
-
// Implementation
|
|
145
|
-
return nil
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// ❌ Bad: Package name stuttering
|
|
149
|
-
type UserService struct{} // Redundant in userservice package
|
|
150
|
-
func NewUserService() *UserService { return nil }
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### 3. Error Handling Patterns | 错误处理模式
|
|
154
|
-
|
|
155
|
-
```go
|
|
156
|
-
import (
|
|
157
|
-
"errors"
|
|
158
|
-
"fmt"
|
|
159
|
-
)
|
|
160
|
-
|
|
161
|
-
// ✅ Good: Idiomatic error handling
|
|
162
|
-
|
|
163
|
-
// Custom error types
|
|
164
|
-
type ValidationError struct {
|
|
165
|
-
Field string
|
|
166
|
-
Message string
|
|
167
|
-
}
|
|
168
|
-
|
|
169
|
-
func (e ValidationError) Error() string {
|
|
170
|
-
return fmt.Sprintf("validation error on field %s: %s", e.Field, e.Message)
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
// Sentinel errors
|
|
174
|
-
var (
|
|
175
|
-
ErrUserNotFound = errors.New("user not found")
|
|
176
|
-
ErrInvalidEmail = errors.New("invalid email address")
|
|
177
|
-
ErrDuplicateUser = errors.New("user already exists")
|
|
178
|
-
)
|
|
179
|
-
|
|
180
|
-
// Error wrapping (Go 1.13+)
|
|
181
|
-
func (s *Service) GetUser(ctx context.Context, id string) (*User, error) {
|
|
182
|
-
user, err := s.db.FindByID(ctx, id)
|
|
183
|
-
if err != nil {
|
|
184
|
-
if errors.Is(err, sql.ErrNoRows) {
|
|
185
|
-
return nil, ErrUserNotFound
|
|
186
|
-
}
|
|
187
|
-
return nil, fmt.Errorf("failed to get user %s: %w", id, err)
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
return user, nil
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
// Multiple return values for error handling
|
|
194
|
-
func (s *Service) CreateUser(ctx context.Context, email, name string) (*User, error) {
|
|
195
|
-
// Validate input
|
|
196
|
-
if email == "" {
|
|
197
|
-
return nil, ValidationError{Field: "email", Message: "cannot be empty"}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if !isValidEmail(email) {
|
|
201
|
-
return nil, ErrInvalidEmail
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
// Check for duplicates
|
|
205
|
-
existing, err := s.db.FindByEmail(ctx, email)
|
|
206
|
-
if err != nil && !errors.Is(err, ErrUserNotFound) {
|
|
207
|
-
return nil, fmt.Errorf("failed to check existing user: %w", err)
|
|
208
|
-
}
|
|
209
|
-
if existing != nil {
|
|
210
|
-
return nil, ErrDuplicateUser
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Create user
|
|
214
|
-
user := &User{
|
|
215
|
-
ID: generateID(),
|
|
216
|
-
Email: email,
|
|
217
|
-
Name: name,
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
if err := s.db.Save(ctx, user); err != nil {
|
|
221
|
-
return nil, fmt.Errorf("failed to save user: %w", err)
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return user, nil
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Error checking in main
|
|
228
|
-
func main() {
|
|
229
|
-
service := NewService(db)
|
|
230
|
-
|
|
231
|
-
user, err := service.CreateUser(ctx, "test@example.com", "Test User")
|
|
232
|
-
if err != nil {
|
|
233
|
-
var validationErr ValidationError
|
|
234
|
-
if errors.As(err, &validationErr) {
|
|
235
|
-
log.Printf("Validation error: %v", validationErr)
|
|
236
|
-
return
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
if errors.Is(err, ErrDuplicateUser) {
|
|
240
|
-
log.Printf("User already exists")
|
|
241
|
-
return
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
log.Printf("Unexpected error: %v", err)
|
|
245
|
-
return
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
fmt.Printf("Created user: %+v\n", user)
|
|
249
|
-
}
|
|
250
|
-
|
|
251
|
-
// ❌ Bad: Poor error handling
|
|
252
|
-
func badCreateUser(email string) *User {
|
|
253
|
-
if email == "" {
|
|
254
|
-
panic("email cannot be empty") // Don't panic for validation
|
|
255
|
-
}
|
|
256
|
-
|
|
257
|
-
user, err := db.Create(email)
|
|
258
|
-
if err != nil {
|
|
259
|
-
log.Println(err) // Don't just log and continue
|
|
260
|
-
return nil
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
return user
|
|
264
|
-
}
|
|
265
|
-
```
|
|
266
|
-
|
|
267
|
-
## Interface Design | 接口设计
|
|
268
|
-
|
|
269
|
-
### 1. Small Interfaces | 小接口
|
|
270
|
-
|
|
271
|
-
```go
|
|
272
|
-
// ✅ Good: Small, focused interfaces
|
|
273
|
-
|
|
274
|
-
// Single method interfaces are common and powerful
|
|
275
|
-
type Reader interface {
|
|
276
|
-
Read([]byte) (int, error)
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
type Writer interface {
|
|
280
|
-
Write([]byte) (int, error)
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
type Closer interface {
|
|
284
|
-
Close() error
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// Compose interfaces
|
|
288
|
-
type ReadWriter interface {
|
|
289
|
-
Reader
|
|
290
|
-
Writer
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
type ReadWriteCloser interface {
|
|
294
|
-
Reader
|
|
295
|
-
Writer
|
|
296
|
-
Closer
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// Domain-specific interfaces
|
|
300
|
-
type UserFinder interface {
|
|
301
|
-
FindByID(ctx context.Context, id string) (*User, error)
|
|
302
|
-
}
|
|
303
|
-
|
|
304
|
-
type UserCreator interface {
|
|
305
|
-
Create(ctx context.Context, user *User) error
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
type UserRepository interface {
|
|
309
|
-
UserFinder
|
|
310
|
-
UserCreator
|
|
311
|
-
Update(ctx context.Context, user *User) error
|
|
312
|
-
Delete(ctx context.Context, id string) error
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
// ✅ Good: Accept interfaces, return structs
|
|
316
|
-
func ProcessUsers(finder UserFinder, ids []string) ([]*User, error) {
|
|
317
|
-
var users []*User
|
|
318
|
-
for _, id := range ids {
|
|
319
|
-
user, err := finder.FindByID(context.Background(), id)
|
|
320
|
-
if err != nil {
|
|
321
|
-
return nil, err
|
|
322
|
-
}
|
|
323
|
-
users = append(users, user)
|
|
324
|
-
}
|
|
325
|
-
return users, nil
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
// ❌ Bad: Large, monolithic interfaces
|
|
329
|
-
type BadUserService interface {
|
|
330
|
-
CreateUser(ctx context.Context, user *User) error
|
|
331
|
-
UpdateUser(ctx context.Context, user *User) error
|
|
332
|
-
DeleteUser(ctx context.Context, id string) error
|
|
333
|
-
FindUser(ctx context.Context, id string) (*User, error)
|
|
334
|
-
ListUsers(ctx context.Context) ([]*User, error)
|
|
335
|
-
AuthenticateUser(ctx context.Context, email, password string) (*User, error)
|
|
336
|
-
SendEmail(ctx context.Context, to, subject, body string) error
|
|
337
|
-
LogActivity(ctx context.Context, activity string) error
|
|
338
|
-
// Too many responsibilities!
|
|
339
|
-
}
|
|
340
|
-
```
|
|
341
|
-
|
|
342
|
-
### 2. Interface Satisfaction | 接口满足
|
|
343
|
-
|
|
344
|
-
```go
|
|
345
|
-
// ✅ Good: Implicit interface satisfaction
|
|
346
|
-
|
|
347
|
-
type Logger interface {
|
|
348
|
-
Log(message string)
|
|
349
|
-
}
|
|
350
|
-
|
|
351
|
-
// This type automatically satisfies Logger interface
|
|
352
|
-
type FileLogger struct {
|
|
353
|
-
filename string
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
func (f *FileLogger) Log(message string) {
|
|
357
|
-
// Write to file
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// This also satisfies Logger interface
|
|
361
|
-
type ConsoleLogger struct{}
|
|
362
|
-
|
|
363
|
-
func (c *ConsoleLogger) Log(message string) {
|
|
364
|
-
fmt.Println(message)
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
// Function that accepts any Logger implementation
|
|
368
|
-
func ProcessWithLogging(logger Logger, data []string) {
|
|
369
|
-
logger.Log("Starting processing")
|
|
370
|
-
|
|
371
|
-
for _, item := range data {
|
|
372
|
-
// Process item
|
|
373
|
-
logger.Log(fmt.Sprintf("Processed: %s", item))
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
logger.Log("Processing complete")
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
// Usage - no explicit interface declaration needed
|
|
380
|
-
func main() {
|
|
381
|
-
fileLogger := &FileLogger{filename: "app.log"}
|
|
382
|
-
consoleLogger := &ConsoleLogger{}
|
|
383
|
-
|
|
384
|
-
data := []string{"item1", "item2", "item3"}
|
|
385
|
-
|
|
386
|
-
ProcessWithLogging(fileLogger, data)
|
|
387
|
-
ProcessWithLogging(consoleLogger, data)
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
// ✅ Good: Empty interface for generic types
|
|
391
|
-
func PrintAny(v interface{}) {
|
|
392
|
-
fmt.Printf("Value: %+v, Type: %T\n", v, v)
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
// Better with generics (Go 1.18+)
|
|
396
|
-
func PrintGeneric[T any](v T) {
|
|
397
|
-
fmt.Printf("Value: %+v, Type: %T\n", v, v)
|
|
398
|
-
}
|
|
399
|
-
```
|
|
400
|
-
|
|
401
|
-
## Goroutines and Concurrency | Goroutines 和并发
|
|
402
|
-
|
|
403
|
-
### 1. Goroutine Patterns | Goroutine 模式
|
|
404
|
-
|
|
405
|
-
```go
|
|
406
|
-
import (
|
|
407
|
-
"context"
|
|
408
|
-
"sync"
|
|
409
|
-
"time"
|
|
410
|
-
)
|
|
411
|
-
|
|
412
|
-
// ✅ Good: Proper goroutine usage with context and synchronization
|
|
413
|
-
|
|
414
|
-
// Worker pool pattern
|
|
415
|
-
func WorkerPool(ctx context.Context, jobs <-chan Job, results chan<- Result, numWorkers int) {
|
|
416
|
-
var wg sync.WaitGroup
|
|
417
|
-
|
|
418
|
-
// Start workers
|
|
419
|
-
for i := 0; i < numWorkers; i++ {
|
|
420
|
-
wg.Add(1)
|
|
421
|
-
go func(workerID int) {
|
|
422
|
-
defer wg.Done()
|
|
423
|
-
|
|
424
|
-
for {
|
|
425
|
-
select {
|
|
426
|
-
case job, ok := <-jobs:
|
|
427
|
-
if !ok {
|
|
428
|
-
return // Channel closed
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
result := processJob(job)
|
|
432
|
-
|
|
433
|
-
select {
|
|
434
|
-
case results <- result:
|
|
435
|
-
case <-ctx.Done():
|
|
436
|
-
return
|
|
437
|
-
}
|
|
438
|
-
|
|
439
|
-
case <-ctx.Done():
|
|
440
|
-
return
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
}(i)
|
|
444
|
-
}
|
|
445
|
-
|
|
446
|
-
wg.Wait()
|
|
447
|
-
close(results)
|
|
448
|
-
}
|
|
449
|
-
|
|
450
|
-
// Fan-out, fan-in pattern
|
|
451
|
-
func FanOutFanIn(ctx context.Context, input <-chan int) <-chan int {
|
|
452
|
-
const numWorkers = 3
|
|
453
|
-
|
|
454
|
-
// Fan-out: distribute work to multiple goroutines
|
|
455
|
-
workers := make([]<-chan int, numWorkers)
|
|
456
|
-
for i := 0; i < numWorkers; i++ {
|
|
457
|
-
worker := make(chan int)
|
|
458
|
-
workers[i] = worker
|
|
459
|
-
|
|
460
|
-
go func(out chan<- int) {
|
|
461
|
-
defer close(out)
|
|
462
|
-
|
|
463
|
-
for n := range input {
|
|
464
|
-
select {
|
|
465
|
-
case out <- expensiveOperation(n):
|
|
466
|
-
case <-ctx.Done():
|
|
467
|
-
return
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
}(worker)
|
|
471
|
-
}
|
|
472
|
-
|
|
473
|
-
// Fan-in: merge results from multiple goroutines
|
|
474
|
-
return merge(ctx, workers...)
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
func merge(ctx context.Context, channels ...<-chan int) <-chan int {
|
|
478
|
-
var wg sync.WaitGroup
|
|
479
|
-
out := make(chan int)
|
|
480
|
-
|
|
481
|
-
// Start a goroutine for each input channel
|
|
482
|
-
output := func(c <-chan int) {
|
|
483
|
-
defer wg.Done()
|
|
484
|
-
for n := range c {
|
|
485
|
-
select {
|
|
486
|
-
case out <- n:
|
|
487
|
-
case <-ctx.Done():
|
|
488
|
-
return
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
wg.Add(len(channels))
|
|
494
|
-
for _, c := range channels {
|
|
495
|
-
go output(c)
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
// Start a goroutine to close out once all output goroutines are done
|
|
499
|
-
go func() {
|
|
500
|
-
wg.Wait()
|
|
501
|
-
close(out)
|
|
502
|
-
}()
|
|
503
|
-
|
|
504
|
-
return out
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
// Pipeline pattern
|
|
508
|
-
func Pipeline(ctx context.Context, input <-chan int) <-chan string {
|
|
509
|
-
// Stage 1: Square numbers
|
|
510
|
-
squared := make(chan int)
|
|
511
|
-
go func() {
|
|
512
|
-
defer close(squared)
|
|
513
|
-
for n := range input {
|
|
514
|
-
select {
|
|
515
|
-
case squared <- n * n:
|
|
516
|
-
case <-ctx.Done():
|
|
517
|
-
return
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
}()
|
|
521
|
-
|
|
522
|
-
// Stage 2: Convert to strings
|
|
523
|
-
strings := make(chan string)
|
|
524
|
-
go func() {
|
|
525
|
-
defer close(strings)
|
|
526
|
-
for n := range squared {
|
|
527
|
-
select {
|
|
528
|
-
case strings <- fmt.Sprintf("Number: %d", n):
|
|
529
|
-
case <-ctx.Done():
|
|
530
|
-
return
|
|
531
|
-
}
|
|
532
|
-
}
|
|
533
|
-
}()
|
|
534
|
-
|
|
535
|
-
return strings
|
|
536
|
-
}
|
|
537
|
-
|
|
538
|
-
// ✅ Good: Graceful shutdown
|
|
539
|
-
type Server struct {
|
|
540
|
-
httpServer *http.Server
|
|
541
|
-
done chan struct{}
|
|
542
|
-
}
|
|
543
|
-
|
|
544
|
-
func (s *Server) Start(addr string) error {
|
|
545
|
-
s.httpServer = &http.Server{Addr: addr}
|
|
546
|
-
s.done = make(chan struct{})
|
|
547
|
-
|
|
548
|
-
go func() {
|
|
549
|
-
if err := s.httpServer.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
|
550
|
-
log.Printf("Server error: %v", err)
|
|
551
|
-
}
|
|
552
|
-
close(s.done)
|
|
553
|
-
}()
|
|
554
|
-
|
|
555
|
-
return nil
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
func (s *Server) Shutdown(ctx context.Context) error {
|
|
559
|
-
if err := s.httpServer.Shutdown(ctx); err != nil {
|
|
560
|
-
return err
|
|
561
|
-
}
|
|
562
|
-
|
|
563
|
-
select {
|
|
564
|
-
case <-s.done:
|
|
565
|
-
return nil
|
|
566
|
-
case <-ctx.Done():
|
|
567
|
-
return ctx.Err()
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
// ❌ Bad: Goroutine leaks and poor synchronization
|
|
572
|
-
func badGoroutineUsage() {
|
|
573
|
-
// No way to stop this goroutine
|
|
574
|
-
go func() {
|
|
575
|
-
for {
|
|
576
|
-
doWork()
|
|
577
|
-
time.Sleep(time.Second)
|
|
578
|
-
}
|
|
579
|
-
}()
|
|
580
|
-
|
|
581
|
-
// Race condition - no synchronization
|
|
582
|
-
var result int
|
|
583
|
-
go func() {
|
|
584
|
-
result = expensiveCalculation()
|
|
585
|
-
}()
|
|
586
|
-
|
|
587
|
-
fmt.Println(result) // May print 0 due to race condition
|
|
588
|
-
}
|
|
589
|
-
```
|
|
590
|
-
|
|
591
|
-
### 2. Channel Patterns | Channel 模式
|
|
592
|
-
|
|
593
|
-
```go
|
|
594
|
-
// ✅ Good: Channel patterns and idioms
|
|
595
|
-
|
|
596
|
-
// Generator pattern
|
|
597
|
-
func NumberGenerator(ctx context.Context, start, end int) <-chan int {
|
|
598
|
-
ch := make(chan int)
|
|
599
|
-
|
|
600
|
-
go func() {
|
|
601
|
-
defer close(ch)
|
|
602
|
-
|
|
603
|
-
for i := start; i <= end; i++ {
|
|
604
|
-
select {
|
|
605
|
-
case ch <- i:
|
|
606
|
-
case <-ctx.Done():
|
|
607
|
-
return
|
|
608
|
-
}
|
|
609
|
-
}
|
|
610
|
-
}()
|
|
611
|
-
|
|
612
|
-
return ch
|
|
613
|
-
}
|
|
614
|
-
|
|
615
|
-
// Timeout pattern
|
|
616
|
-
func WithTimeout(operation func() (string, error), timeout time.Duration) (string, error) {
|
|
617
|
-
type result struct {
|
|
618
|
-
value string
|
|
619
|
-
err error
|
|
620
|
-
}
|
|
621
|
-
|
|
622
|
-
ch := make(chan result, 1)
|
|
623
|
-
|
|
624
|
-
go func() {
|
|
625
|
-
value, err := operation()
|
|
626
|
-
ch <- result{value: value, err: err}
|
|
627
|
-
}()
|
|
628
|
-
|
|
629
|
-
select {
|
|
630
|
-
case res := <-ch:
|
|
631
|
-
return res.value, res.err
|
|
632
|
-
case <-time.After(timeout):
|
|
633
|
-
return "", fmt.Errorf("operation timed out after %v", timeout)
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// Rate limiting pattern
|
|
638
|
-
func RateLimiter(rate time.Duration) <-chan time.Time {
|
|
639
|
-
return time.Tick(rate)
|
|
640
|
-
}
|
|
641
|
-
|
|
642
|
-
func ProcessWithRateLimit(items []string, rate time.Duration) {
|
|
643
|
-
limiter := RateLimiter(rate)
|
|
644
|
-
|
|
645
|
-
for _, item := range items {
|
|
646
|
-
<-limiter // Wait for rate limiter
|
|
647
|
-
processItem(item)
|
|
648
|
-
}
|
|
649
|
-
}
|
|
650
|
-
|
|
651
|
-
// Semaphore pattern for limiting concurrency
|
|
652
|
-
type Semaphore chan struct{}
|
|
653
|
-
|
|
654
|
-
func NewSemaphore(capacity int) Semaphore {
|
|
655
|
-
return make(Semaphore, capacity)
|
|
656
|
-
}
|
|
657
|
-
|
|
658
|
-
func (s Semaphore) Acquire() {
|
|
659
|
-
s <- struct{}{}
|
|
660
|
-
}
|
|
661
|
-
|
|
662
|
-
func (s Semaphore) Release() {
|
|
663
|
-
<-s
|
|
664
|
-
}
|
|
665
|
-
|
|
666
|
-
func ProcessConcurrently(items []string, maxConcurrency int) {
|
|
667
|
-
sem := NewSemaphore(maxConcurrency)
|
|
668
|
-
var wg sync.WaitGroup
|
|
669
|
-
|
|
670
|
-
for _, item := range items {
|
|
671
|
-
wg.Add(1)
|
|
672
|
-
|
|
673
|
-
go func(item string) {
|
|
674
|
-
defer wg.Done()
|
|
675
|
-
|
|
676
|
-
sem.Acquire()
|
|
677
|
-
defer sem.Release()
|
|
678
|
-
|
|
679
|
-
processItem(item)
|
|
680
|
-
}(item)
|
|
681
|
-
}
|
|
682
|
-
|
|
683
|
-
wg.Wait()
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
// Select with default for non-blocking operations
|
|
687
|
-
func TryReceive(ch <-chan string) (string, bool) {
|
|
688
|
-
select {
|
|
689
|
-
case value := <-ch:
|
|
690
|
-
return value, true
|
|
691
|
-
default:
|
|
692
|
-
return "", false
|
|
693
|
-
}
|
|
694
|
-
}
|
|
695
|
-
|
|
696
|
-
func TrySend(ch chan<- string, value string) bool {
|
|
697
|
-
select {
|
|
698
|
-
case ch <- value:
|
|
699
|
-
return true
|
|
700
|
-
default:
|
|
701
|
-
return false
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
```
|
|
705
|
-
|
|
706
|
-
## Memory Management and Performance | 内存管理和性能
|
|
707
|
-
|
|
708
|
-
### 1. Efficient Memory Usage | 高效内存使用
|
|
709
|
-
|
|
710
|
-
```go
|
|
711
|
-
import (
|
|
712
|
-
"bytes"
|
|
713
|
-
"strings"
|
|
714
|
-
)
|
|
715
|
-
|
|
716
|
-
// ✅ Good: Efficient string building
|
|
717
|
-
func BuildString(parts []string) string {
|
|
718
|
-
var builder strings.Builder
|
|
719
|
-
|
|
720
|
-
// Pre-allocate capacity if known
|
|
721
|
-
totalLen := 0
|
|
722
|
-
for _, part := range parts {
|
|
723
|
-
totalLen += len(part)
|
|
724
|
-
}
|
|
725
|
-
builder.Grow(totalLen)
|
|
726
|
-
|
|
727
|
-
for _, part := range parts {
|
|
728
|
-
builder.WriteString(part)
|
|
729
|
-
}
|
|
730
|
-
|
|
731
|
-
return builder.String()
|
|
732
|
-
}
|
|
733
|
-
|
|
734
|
-
// ✅ Good: Efficient slice operations
|
|
735
|
-
func ProcessLargeSlice(data []int) []int {
|
|
736
|
-
// Pre-allocate with known capacity
|
|
737
|
-
result := make([]int, 0, len(data))
|
|
738
|
-
|
|
739
|
-
for _, item := range data {
|
|
740
|
-
if item > 0 {
|
|
741
|
-
result = append(result, item*2)
|
|
742
|
-
}
|
|
743
|
-
}
|
|
744
|
-
|
|
745
|
-
return result
|
|
746
|
-
}
|
|
747
|
-
|
|
748
|
-
// ✅ Good: Reuse slices to reduce allocations
|
|
749
|
-
type Processor struct {
|
|
750
|
-
buffer []byte
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
func NewProcessor() *Processor {
|
|
754
|
-
return &Processor{
|
|
755
|
-
buffer: make([]byte, 0, 1024), // Pre-allocate buffer
|
|
756
|
-
}
|
|
757
|
-
}
|
|
758
|
-
|
|
759
|
-
func (p *Processor) Process(data []byte) []byte {
|
|
760
|
-
// Reuse buffer, reset length but keep capacity
|
|
761
|
-
p.buffer = p.buffer[:0]
|
|
762
|
-
|
|
763
|
-
// Process data into buffer
|
|
764
|
-
for _, b := range data {
|
|
765
|
-
if b != 0 {
|
|
766
|
-
p.buffer = append(p.buffer, b)
|
|
767
|
-
}
|
|
768
|
-
}
|
|
769
|
-
|
|
770
|
-
// Return copy to avoid sharing internal buffer
|
|
771
|
-
result := make([]byte, len(p.buffer))
|
|
772
|
-
copy(result, p.buffer)
|
|
773
|
-
|
|
774
|
-
return result
|
|
775
|
-
}
|
|
776
|
-
|
|
777
|
-
// ✅ Good: Pool pattern for expensive objects
|
|
778
|
-
var bufferPool = sync.Pool{
|
|
779
|
-
New: func() interface{} {
|
|
780
|
-
return make([]byte, 0, 1024)
|
|
781
|
-
},
|
|
782
|
-
}
|
|
783
|
-
|
|
784
|
-
func ProcessWithPool(data []byte) []byte {
|
|
785
|
-
// Get buffer from pool
|
|
786
|
-
buffer := bufferPool.Get().([]byte)
|
|
787
|
-
defer bufferPool.Put(buffer[:0]) // Reset and return to pool
|
|
788
|
-
|
|
789
|
-
// Use buffer for processing
|
|
790
|
-
for _, b := range data {
|
|
791
|
-
if b > 0 {
|
|
792
|
-
buffer = append(buffer, b*2)
|
|
793
|
-
}
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
// Return copy
|
|
797
|
-
result := make([]byte, len(buffer))
|
|
798
|
-
copy(result, buffer)
|
|
799
|
-
|
|
800
|
-
return result
|
|
801
|
-
}
|
|
802
|
-
|
|
803
|
-
// ❌ Bad: Inefficient memory usage
|
|
804
|
-
func badStringBuilding(parts []string) string {
|
|
805
|
-
result := ""
|
|
806
|
-
for _, part := range parts {
|
|
807
|
-
result += part // Creates new string each time
|
|
808
|
-
}
|
|
809
|
-
return result
|
|
810
|
-
}
|
|
811
|
-
|
|
812
|
-
func badSliceGrowth() []int {
|
|
813
|
-
var result []int
|
|
814
|
-
for i := 0; i < 1000000; i++ {
|
|
815
|
-
result = append(result, i) // Frequent reallocations
|
|
816
|
-
}
|
|
817
|
-
return result
|
|
818
|
-
}
|
|
819
|
-
```
|
|
820
|
-
|
|
821
|
-
### 2. Benchmarking and Profiling | 基准测试和性能分析
|
|
822
|
-
|
|
823
|
-
```go
|
|
824
|
-
import (
|
|
825
|
-
"testing"
|
|
826
|
-
)
|
|
827
|
-
|
|
828
|
-
// ✅ Good: Proper benchmarking
|
|
829
|
-
func BenchmarkStringBuilding(b *testing.B) {
|
|
830
|
-
parts := []string{"hello", " ", "world", "!"}
|
|
831
|
-
|
|
832
|
-
b.ResetTimer()
|
|
833
|
-
|
|
834
|
-
for i := 0; i < b.N; i++ {
|
|
835
|
-
_ = BuildString(parts)
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
func BenchmarkStringBuildingWithAlloc(b *testing.B) {
|
|
840
|
-
parts := []string{"hello", " ", "world", "!"}
|
|
841
|
-
|
|
842
|
-
b.ResetTimer()
|
|
843
|
-
b.ReportAllocs()
|
|
844
|
-
|
|
845
|
-
for i := 0; i < b.N; i++ {
|
|
846
|
-
_ = BuildString(parts)
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
// Benchmark different approaches
|
|
851
|
-
func BenchmarkProcessingApproaches(b *testing.B) {
|
|
852
|
-
data := make([]int, 1000)
|
|
853
|
-
for i := range data {
|
|
854
|
-
data[i] = i
|
|
855
|
-
}
|
|
856
|
-
|
|
857
|
-
b.Run("WithPrealloc", func(b *testing.B) {
|
|
858
|
-
for i := 0; i < b.N; i++ {
|
|
859
|
-
_ = ProcessLargeSlice(data)
|
|
860
|
-
}
|
|
861
|
-
})
|
|
862
|
-
|
|
863
|
-
b.Run("WithoutPrealloc", func(b *testing.B) {
|
|
864
|
-
for i := 0; i < b.N; i++ {
|
|
865
|
-
var result []int
|
|
866
|
-
for _, item := range data {
|
|
867
|
-
if item > 0 {
|
|
868
|
-
result = append(result, item*2)
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
})
|
|
873
|
-
}
|
|
874
|
-
|
|
875
|
-
// Example benchmark output:
|
|
876
|
-
// BenchmarkStringBuilding-8 1000000 1043 ns/op
|
|
877
|
-
// BenchmarkStringBuildingWithAlloc-8 1000000 1043 ns/op 32 B/op 2 allocs/op
|
|
878
|
-
```
|
|
879
|
-
|
|
880
|
-
## Testing Patterns | 测试模式
|
|
881
|
-
|
|
882
|
-
### 1. Table-Driven Tests | 表驱动测试
|
|
883
|
-
|
|
884
|
-
```go
|
|
885
|
-
func TestValidateEmail(t *testing.T) {
|
|
886
|
-
tests := []struct {
|
|
887
|
-
name string
|
|
888
|
-
email string
|
|
889
|
-
want bool
|
|
890
|
-
wantErr bool
|
|
891
|
-
}{
|
|
892
|
-
{
|
|
893
|
-
name: "valid email",
|
|
894
|
-
email: "test@example.com",
|
|
895
|
-
want: true,
|
|
896
|
-
wantErr: false,
|
|
897
|
-
},
|
|
898
|
-
{
|
|
899
|
-
name: "invalid email - no @",
|
|
900
|
-
email: "testexample.com",
|
|
901
|
-
want: false,
|
|
902
|
-
wantErr: true,
|
|
903
|
-
},
|
|
904
|
-
{
|
|
905
|
-
name: "invalid email - no domain",
|
|
906
|
-
email: "test@",
|
|
907
|
-
want: false,
|
|
908
|
-
wantErr: true,
|
|
909
|
-
},
|
|
910
|
-
{
|
|
911
|
-
name: "empty email",
|
|
912
|
-
email: "",
|
|
913
|
-
want: false,
|
|
914
|
-
wantErr: true,
|
|
915
|
-
},
|
|
916
|
-
}
|
|
917
|
-
|
|
918
|
-
for _, tt := range tests {
|
|
919
|
-
t.Run(tt.name, func(t *testing.T) {
|
|
920
|
-
got, err := ValidateEmail(tt.email)
|
|
921
|
-
|
|
922
|
-
if (err != nil) != tt.wantErr {
|
|
923
|
-
t.Errorf("ValidateEmail() error = %v, wantErr %v", err, tt.wantErr)
|
|
924
|
-
return
|
|
925
|
-
}
|
|
926
|
-
|
|
927
|
-
if got != tt.want {
|
|
928
|
-
t.Errorf("ValidateEmail() = %v, want %v", got, tt.want)
|
|
929
|
-
}
|
|
930
|
-
})
|
|
931
|
-
}
|
|
932
|
-
}
|
|
933
|
-
```
|
|
934
|
-
|
|
935
|
-
## Code Quality Checklist | 代码质量检查清单
|
|
936
|
-
|
|
937
|
-
- [ ] Follow Go naming conventions (CamelCase, short names)
|
|
938
|
-
- [ ] Handle errors explicitly, don't ignore them
|
|
939
|
-
- [ ] Use small, focused interfaces
|
|
940
|
-
- [ ] Accept interfaces, return concrete types
|
|
941
|
-
- [ ] Use context.Context for cancellation and timeouts
|
|
942
|
-
- [ ] Avoid goroutine leaks with proper cleanup
|
|
943
|
-
- [ ] Use channels for communication, not shared memory
|
|
944
|
-
- [ ] Pre-allocate slices and maps when size is known
|
|
945
|
-
- [ ] Use sync.Pool for expensive object reuse
|
|
946
|
-
- [ ] Write table-driven tests for comprehensive coverage
|
|
947
|
-
- [ ] Use go fmt, go vet, and golint tools
|
|
948
|
-
- [ ] Profile and benchmark performance-critical code
|
|
949
|
-
|
|
950
|
-
## 代码质量检查清单
|
|
951
|
-
|
|
952
|
-
- [ ] 遵循 Go 命名约定(CamelCase,简短名称)
|
|
953
|
-
- [ ] 明确处理错误,不要忽略它们
|
|
954
|
-
- [ ] 使用小而专注的接口
|
|
955
|
-
- [ ] 接受接口,返回具体类型
|
|
956
|
-
- [ ] 使用 context.Context 进行取消和超时
|
|
957
|
-
- [ ] 通过适当的清理避免 goroutine 泄漏
|
|
958
|
-
- [ ] 使用 channel 进行通信,而不是共享内存
|
|
959
|
-
- [ ] 在已知大小时预分配切片和映射
|
|
960
|
-
- [ ] 使用 sync.Pool 进行昂贵对象重用
|
|
961
|
-
- [ ] 编写表驱动测试以获得全面覆盖
|
|
962
|
-
- [ ] 使用 go fmt、go vet 和 golint 工具
|
|
963
|
-
- [ ] 对性能关键代码进行性能分析和基准测试
|