Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .goreleaser.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ builds:
- -X github.com/lazygophers/utils/app.Gomips={{ .Mips }}
gcflags:
- -N -l
main: ./cmd/
targets:
- linux_amd64_v3
- linux_arm64
Expand Down
60 changes: 59 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -170,4 +170,62 @@ When translating:

3. **Overwrite protection**: By default, impl files won't be overwritten. Use `--overwrite` flag with caution.

4. **Lazy config**: The tool looks for `.lazygophers` file in the project root (determined by go_package). This configures project-specific generation options.
4. **Lazy config**: The tool looks for `.lazygophers` file in the project root (determined by go_package). This configures project-specific generation options.

## Development Guidelines

### Core Development Principles

- **Memory Management**: When users say "remember xxx" or repeatedly emphasize certain rules, behaviors, etc., automatically update relevant memory banks and documentation
- **Code Analysis**: Before coding, analyze at least 3 existing implementations or patterns to identify reusable interfaces and constraints
- **Dependency Mapping**: Draw dependencies and integration points, confirming input/output protocols, configuration, and environment requirements
- **Code Consistency**: Understand existing testing frameworks, naming conventions, and formatting rules to ensure output aligns with the codebase
- **Documentation Priority**: Use context7 to query programming library documentation first, avoid over-reliance on web searches or assumptions
- **Best Practice Learning**: Use github.search_code to search open-source implementation examples and learn best practices
- **Complete Implementation**: Absolutely prohibit MVP, minimal implementations, or placeholders; full functionality and data paths must be completed before submission
- **Code Cleanup**: Must improve all MVP, minimal implementations, and placeholders to complete, concrete code implementations
- **Active Cleanup**: Must proactively delete outdated, duplicate, or escape-style code to maintain clean implementations
- **Style Consistency**: Must always adhere to programming language standard code styles and project-specific style specifications
- **Breaking Changes**: Do not maintain backward compatibility for breaking changes, while providing migration steps or rollback plans
- **Disruptive Strategy**: Must always adopt disruptive breaking change strategy, absolutely no backward compatibility
- **Quality Assurance**: Must follow best practices to ensure code quality and maintainability
- **Language-Specific Patterns**: Absolutely prohibit using Java-style coding standards to write code or documentation in other languages
- **Performance Evaluation**: Must evaluate time complexity, memory usage, and I/O impact during design to avoid unnecessary consumption
- **Optimization Awareness**: After identifying potential bottlenecks, provide monitoring or optimization suggestions to ensure sustainable iteration
- **Dependency Assessment**: Prohibit introducing unevaluated expensive dependencies or blocking operations

## 🔧 Project Integration Rules

### Learning the Codebase
- Must find at least 3 similar features or components to understand their design and reuse patterns
- Must identify common patterns and conventions in the project and apply them in new implementations
- Must prioritize using existing libraries, tools, or helper functions
- Must follow existing testing arrangements and沿用 assertion and fixture structures

### Tools
- Must use the project's existing build system, no private addition of scripts
- Must use the project's established testing framework and execution methods
- Must use the project's formatting/static checking settings
- If there is indeed a need for new tools, must provide sufficient justification and obtain documented approval

## ⚠️ Important Reminders

**Absolutely Prohibited:**
- Making assumptions without evidence; all conclusions must cite existing code or documentation

**Must Be Done:**
- Complete detailed planning and documentation before implementing complex tasks
- Generate task decomposition for cross-module or more than 5 subtasks work
- Maintain TODO lists for complex tasks and update progress in a timely manner
- Verify planning documents are confirmed before starting development
- Maintain small-step delivery, ensuring each commit is in a usable state
- Synchronously update planning documents and progress records during execution
- Proactively learn the advantages and disadvantages of existing implementations and reuse or improve them
- Must pause operations after three consecutive failures and reassess strategy

## 🎯 Content Uniqueness Rules

- Each level must be self-consistent in mastering its own abstract scope, prohibiting cross-level content mixing
- Must reference materials from other levels rather than copy-pasting, maintaining unique information sources
- Each level must describe the system from the corresponding perspective, avoiding overreaching details
- Prohibit stacking implementation details in high-level documents, ensuring clear architecture and implementation boundaries
1 change: 1 addition & 0 deletions cli/gen/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ func initGen() {
initCache()
initCmd()
initConf()
initDoc()
initEditorconfig()
initGolangLint()
initGoreleaser()
Expand Down
43 changes: 43 additions & 0 deletions cli/gen/gen_doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
package gen

import (
"github.com/lazygophers/codegen/cli/utils"
"github.com/lazygophers/codegen/codegen"
"github.com/lazygophers/codegen/state"
"github.com/lazygophers/log"
"github.com/lazygophers/lrpc/middleware/i18n"
"github.com/spf13/cobra"
)

var docCmd = &cobra.Command{
Use: "doc",
RunE: runGenDoc,
}

var runGenDoc = func(cmd *cobra.Command, args []string) (err error) {
mergeDocFlags(cmd)

err = codegen.GenerateDoc(pb)
if err != nil {
log.Errorf("err:%v", err)
return err
}

return nil
}

func mergeDocFlags(cmd *cobra.Command) {
if utils.Changed("doc-language", cmd) {
state.Config.Language = utils.GetString("doc-language", cmd)
}
}

func initDoc() {
docCmd.Short = state.Localize(state.I18nTagCliGenDocShort)
docCmd.Long = state.Localize(state.I18nTagCliGenDocLong)

docCmd.Flags().String("doc-language", i18n.DefaultLanguage(), state.Localize(state.I18nTagCliGenDocFlagsLanguage))
docCmd.Flags().String("doc-output-dir", "docs", state.Localize(state.I18nTagCliGenDocFlagsOutputDir))

genCmd.AddCommand(docCmd)
}
4 changes: 2 additions & 2 deletions cli/gen/gen_i18n.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ func runGenI18n(c *cobra.Command, args []string) (err error) {
}

func initI18n() {
i18nCmd.Short = state.Localize(state.I18nTagCliGenStateI18nShort)
i18nCmd.Long = state.Localize(state.I18nTagCliGenStateI18nLong)
i18nCmd.Short = state.Localize(state.I18nTagCliGenStateI18NShort)
i18nCmd.Long = state.Localize(state.I18nTagCliGenStateI18NLong)

stateCmd.AddCommand(i18nCmd)
}
2 changes: 1 addition & 1 deletion cli/gen/gen_state.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func mergeStateFlags(cmd *cobra.Command) {
func initStateFlags(cmd *cobra.Command) {
cmd.PersistentFlags().Bool("table", state.Config.State.Table, state.Localize(state.I18nTagCliGenStateFlagsTable))
cmd.PersistentFlags().Bool("cache", state.Config.State.Cache, state.Localize(state.I18nTagCliGenStateFlagsCache))
cmd.PersistentFlags().Bool("i18n", state.Config.State.I18n, state.Localize(state.I18nTagCliGenStateFlagsI18n))
cmd.PersistentFlags().Bool("i18n", state.Config.State.I18n, state.Localize(state.I18nTagCliGenStateFlagsI18N))
cmd.PersistentFlags().Bool("config", state.Config.State.Config, state.Localize(state.I18nTagCliGenStateFlagsConfig))
initStateTableFlags(cmd)
}
Expand Down
4 changes: 2 additions & 2 deletions cli/i18n/i18n.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ var i18nCmd = &cobra.Command{
}

func Load(rootCmd *cobra.Command) {
i18nCmd.Short = state.Localize(state.I18nTagCliI18nShort)
i18nCmd.Long = state.Localize(state.I18nTagCliI18nLong)
i18nCmd.Short = state.Localize(state.I18nTagCliI18NShort)
i18nCmd.Long = state.Localize(state.I18nTagCliI18NLong)

rootCmd.AddCommand(i18nCmd)

Expand Down
6 changes: 3 additions & 3 deletions cli/i18n/supported.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ var supportedCmd = &cobra.Command{
}

func initSupport() {
supportedCmd.Short = state.Localize(state.I18nTagCliI18nSupportShort)
supportedCmd.Long = state.Localize(state.I18nTagCliI18nSupportLong)
supportedCmd.Short = state.Localize(state.I18nTagCliI18NSupportShort)
supportedCmd.Long = state.Localize(state.I18nTagCliI18NSupportLong)

supportedCmd.Flags().String("language", "", state.Localize(state.I18nTagCliI18nSupportFlagsLanguage))
supportedCmd.Flags().String("language", "", state.Localize(state.I18nTagCliI18NSupportFlagsLanguage))

i18nCmd.AddCommand(supportedCmd)
}
28 changes: 14 additions & 14 deletions cli/i18n/tran.go
Original file line number Diff line number Diff line change
Expand Up @@ -319,29 +319,29 @@ func mergeTranCmdFlags(cmd *cobra.Command) {
}

func initTran() {
tranCmd.Short = state.Localize(state.I18nTagCliI18nTranShort)
tranCmd.Long = state.Localize(state.I18nTagCliI18nLong)
tranCmd.Short = state.Localize(state.I18nTagCliI18NTranShort)
tranCmd.Long = state.Localize(state.I18nTagCliI18NLong)

tranCmd.Flags().StringP("src-file", "s", "", state.Localize(state.I18nTagCliI18nTranFlagsSrcFile))
tranCmd.Flags().String("src-language", "", state.Localize(state.I18nTagCliI18nTranFlagsSrcLanguage))
tranCmd.Flags().StringP("src-file", "s", "", state.Localize(state.I18nTagCliI18NTranFlagsSrcFile))
tranCmd.Flags().String("src-language", "", state.Localize(state.I18nTagCliI18NTranFlagsSrcLanguage))

tranCmd.Flags().Bool("all-languages", state.Config.I18n.AllLanguages, state.Localize(state.I18nTagCliI18nTranFlagsAllLanguage))
tranCmd.Flags().StringSliceP("languages", "l", state.Config.I18n.Languages, state.Localize(state.I18nTagCliI18nTranFlagsLanguages))
tranCmd.Flags().Bool("all-languages", state.Config.I18n.AllLanguages, state.Localize(state.I18nTagCliI18NTranFlagsAllLanguage))
tranCmd.Flags().StringSliceP("languages", "l", state.Config.I18n.Languages, state.Localize(state.I18nTagCliI18NTranFlagsLanguages))

tranCmd.Flags().Bool("generate-const", state.Config.I18n.GenerateConst, state.Localize(state.I18nTagCliI18nTranFlagsGenerateConst))
tranCmd.Flags().Bool("generate-field", state.Config.I18n.GenerateField, state.Localize(state.I18nTagCliI18nTranFlagsGenerateField))
tranCmd.Flags().String("translator", state.Config.I18n.Translator, state.Localize(state.I18nTagCliI18nTranFlagsTranslatorUsage, map[string]any{
tranCmd.Flags().Bool("generate-const", state.Config.I18n.GenerateConst, state.Localize(state.I18nTagCliI18NTranFlagsGenerateConst))
tranCmd.Flags().Bool("generate-field", state.Config.I18n.GenerateField, state.Localize(state.I18nTagCliI18NTranFlagsGenerateField))
tranCmd.Flags().String("translator", state.Config.I18n.Translator, state.Localize(state.I18nTagCliI18NTranFlagsTranslatorUsage, map[string]any{
"Type": map[i18n.TranslateType]string{
i18n.TranslateTypeGoogleFree: state.Localize(state.I18nTagCliI18nTranFlagsTranslatorGoogleFree),
i18n.TranslateTypeGoogleFree: state.Localize(state.I18nTagCliI18NTranFlagsTranslatorGoogleFree),
},
}))

tranCmd.Flags().Bool("auto-tran-enable-record", state.Config.I18n.AutoTran.EnableRecord, state.Localize(state.I18nTagCliI18nTranFlagsAutoTran))
tranCmd.Flags().String("auto-tran-record-path", state.Config.I18n.AutoTran.RecordPath, state.Localize(state.I18nTagCliI18nTranFlagsAutoTranRecordPath))
tranCmd.Flags().Bool("auto-tran-enable-record", state.Config.I18n.AutoTran.EnableRecord, state.Localize(state.I18nTagCliI18NTranFlagsAutoTran))
tranCmd.Flags().String("auto-tran-record-path", state.Config.I18n.AutoTran.RecordPath, state.Localize(state.I18nTagCliI18NTranFlagsAutoTranRecordPath))

tranCmd.Flags().StringSlice("force-key-prefix", []string{}, state.Localize(state.I18nTagCliI18nTranFlagsForce))
tranCmd.Flags().StringSlice("force-key-prefix", []string{}, state.Localize(state.I18nTagCliI18NTranFlagsForce))

tranCmd.Flags().BoolP("force", "f", false, state.Localize(state.I18nTagCliI18nTranFlagsForce))
tranCmd.Flags().BoolP("force", "f", false, state.Localize(state.I18nTagCliI18NTranFlagsForce))

i18nCmd.AddCommand(tranCmd)
}
4 changes: 2 additions & 2 deletions cli/sync.go
Original file line number Diff line number Diff line change
Expand Up @@ -305,7 +305,7 @@ func syncFromRemote(c *state.Cfg) error {

if resp.StatusCode() != http.StatusOK {
log.Errorf("unexpected status code: %v", resp.StatusCode())
return xerror.NewError(int32(resp.StatusCode()))
return xerror.New(int32(resp.StatusCode()))
}

ext := filepath.Ext(c.Sync.Remote)
Expand Down Expand Up @@ -430,7 +430,7 @@ func syncFromRemote(c *state.Cfg) error {
if resp.StatusCode() != http.StatusOK {
log.Errorf("get template from %s", resp.Request.URL)
log.Errorf("unexpected status code: %v", resp.StatusCode())
return xerror.NewError(int32(resp.StatusCode()))
return xerror.New(int32(resp.StatusCode()))
}

// md5+原始文件名,如果文件没有变更就可以不用写文件了
Expand Down
37 changes: 19 additions & 18 deletions codegen/check.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,12 @@ package codegen
import (
"errors"
"fmt"
"os/exec"
"strings"

"github.com/lazygophers/codegen/state"
"github.com/lazygophers/log"
"github.com/pterm/pterm"
"os/exec"
"strings"
)

const (
Expand All @@ -22,10 +23,10 @@ const (

// commandCheckConfig holds configuration for checking a command
type commandCheckConfig struct {
cmdPath string
cmdName string
notFoundMsg string
installGuide string
cmdPath string
cmdName string
notFoundMsg string
installGuide string
shouldPrintVersion bool
}

Expand Down Expand Up @@ -89,10 +90,10 @@ func printVersion(cfg commandCheckConfig, cmdPath string) error {
func CheckEnvironments() error {
// Check protoc
err := checkCommand(commandCheckConfig{
cmdPath: state.Config.ProtocPath,
cmdName: "protoc",
notFoundMsg: protocNotFoundMsg,
installGuide: protocInstallGuide,
cmdPath: state.Config.ProtocPath,
cmdName: "protoc",
notFoundMsg: protocNotFoundMsg,
installGuide: protocInstallGuide,
shouldPrintVersion: true,
})
if err != nil {
Expand All @@ -102,10 +103,10 @@ func CheckEnvironments() error {

// Check protoc-gen-go
err = checkCommand(commandCheckConfig{
cmdPath: state.Config.ProtoGenGoPath,
cmdName: "protoc-gen-go",
notFoundMsg: protocGenGoNotFoundMsg,
installGuide: protocGenGoInstallGuide,
cmdPath: state.Config.ProtoGenGoPath,
cmdName: "protoc-gen-go",
notFoundMsg: protocGenGoNotFoundMsg,
installGuide: protocGenGoInstallGuide,
shouldPrintVersion: true,
})
if err != nil {
Expand All @@ -115,10 +116,10 @@ func CheckEnvironments() error {

// Check protoc-gen-go-grpc
err = checkCommand(commandCheckConfig{
cmdPath: state.Config.ProtoGenGoGrpcPath,
cmdName: "protoc-gen-go-grpc",
notFoundMsg: protocGenGoGrpcNotFoundMsg,
installGuide: protocGenGoGrpcInstallGuide,
cmdPath: state.Config.ProtoGenGoGrpcPath,
cmdName: "protoc-gen-go-grpc",
notFoundMsg: protocGenGoGrpcNotFoundMsg,
installGuide: protocGenGoGrpcInstallGuide,
shouldPrintVersion: true,
})
if err != nil {
Expand Down
Loading
Loading