diff --git a/tool/cmd/kitex/args/args.go b/tool/cmd/kitex/args/args.go index 5adf00575e..5bde7a68f4 100644 --- a/tool/cmd/kitex/args/args.go +++ b/tool/cmd/kitex/args/args.go @@ -16,11 +16,13 @@ package args import ( "context" + "errors" "flag" "fmt" "io" "os" "os/exec" + "path" "path/filepath" "regexp" "strconv" @@ -270,50 +272,74 @@ func (a *Arguments) checkStreamX() error { return nil } -func (a *Arguments) checkPath(curpath string) error { - pathToGo, err := exec.LookPath("go") +// refGoSrcPath returns ref path to curpath, base path is $GOPATH/src +func refGoSrcPath(curpath string) (string, bool) { + gopath, err := util.GetGOPATH() if err != nil { - return err + return "", false } - - gopath, err := util.GetGOPATH() + gosrc, err := filepath.Abs(filepath.Join(gopath, "src")) if err != nil { - return err + return "", false + } + // if curpath is NOT under gosrc + if !strings.HasPrefix(curpath, gosrc) { + return "", false } - gosrc := util.JoinPath(gopath, "src") - gosrc, err = filepath.Abs(gosrc) + ret, err := filepath.Rel(gosrc, curpath) if err != nil { - return fmt.Errorf("get GOPATH/src path failed: %s", err.Error()) + return "", false } + return ret, true +} - if strings.HasPrefix(curpath, gosrc) { - if a.PackagePrefix, err = filepath.Rel(gosrc, curpath); err != nil { - return fmt.Errorf("get GOPATH/src relpath failed: %s", err.Error()) - } - a.PackagePrefix = util.JoinPath(a.PackagePrefix, a.GenPath) - } else { - if a.ModuleName == "" { - return fmt.Errorf("outside of $GOPATH. Please specify a module name with the '-module' flag") +func (a *Arguments) checkPath(curpath string) error { + genPath := filepath.ToSlash(a.GenPath) // for PackagePrefix + usingGOPATH := false + + // Try to get ref path to $GOPARH/src for PackagePrefix + // Deprecated: to be removed in the future + if ref, ok := refGoSrcPath(curpath); ok { + usingGOPATH = true + a.PackagePrefix = path.Join(filepath.ToSlash(ref), genPath) + } + + goMod, goModPath, hasGoMod := util.SearchGoMod(curpath) + if usingGOPATH && a.ModuleName == "" && !hasGoMod { + log.Warn("You're relying on $GOPATH for generating code.\n" + + "Please add go.mod or specify -module for module path.\n" + + "We will deprecate $GOPATH support in the near future!") + } + + if !usingGOPATH && a.ModuleName == "" { + // try to update a.ModuleName with module name from go.mod + if hasGoMod { + a.ModuleName = goMod + } else { + // case: + // * -module not set + // * not under $GOPATH/src + // * go.mod not found + return errors.New("Please specify a module name with the '-module' flag") } } if a.ModuleName != "" { - module, path, ok := util.SearchGoMod(curpath) - if ok { - // go.mod exists - if module != a.ModuleName { + if hasGoMod { + if goMod != a.ModuleName { return fmt.Errorf("the module name given by the '-module' option ('%s') is not consist with the name defined in go.mod ('%s' from %s)", - a.ModuleName, module, path) + a.ModuleName, goMod, goModPath) } - if a.PackagePrefix, err = filepath.Rel(path, curpath); err != nil { - return fmt.Errorf("get package prefix failed: %s", err.Error()) + refPath, err := filepath.Rel(goModPath, curpath) + if err != nil { + return fmt.Errorf("get package prefix failed: %w", err) } - a.PackagePrefix = util.JoinPath(a.ModuleName, a.PackagePrefix, a.GenPath) + a.PackagePrefix = path.Join(a.ModuleName, filepath.ToSlash(refPath), genPath) } else { - if err = initGoMod(pathToGo, a.ModuleName); err != nil { - return fmt.Errorf("init go mod failed: %s", err.Error()) + if err := initGoMod(a.ModuleName); err != nil { + return fmt.Errorf("init go mod failed: %w", err) } - a.PackagePrefix = util.JoinPath(a.ModuleName, a.GenPath) + a.PackagePrefix = path.Join(a.ModuleName, genPath) } } @@ -541,11 +567,14 @@ func LookupTool(idlType, compilerPath string) string { return path } -func initGoMod(pathToGo, module string) error { +func initGoMod(module string) error { if util.Exists("go.mod") { return nil } - + pathToGo, err := exec.LookPath("go") + if err != nil { + return err + } cmd := &exec.Cmd{ Path: pathToGo, Args: []string{"go", "mod", "init", module},