diff --git a/pkg/README.md b/pkg/README.md index fb33ee9..79f7884 100644 --- a/pkg/README.md +++ b/pkg/README.md @@ -22,14 +22,19 @@ This section is empty. ## Variables +
+var ErrModuleNameMissing = errors.New("failed to find module name") +var ErrGoModMissing = errors.New("unable to find go.mod") +
var Markdown string // value from template.md file +var ErrManyPackagesInDir = errors.New("can only handle one package per directory") var ErrNoPackageFound = errors.New("couldn't find package from ")## Functions -### func [RunDirTree](./run.go#L132) +### func [RunDirTree](./run.go#L131)
func RunDirTree(out OutputSettings, version string, includeMain bool) error @@ -38,7 +43,7 @@ RunDirTree checks given directory and its subdirectories with RunDirectory(). Ignores all ErrNoPackageFound errors from RunDirectory. -### func [RunDirectory](./run.go#L122) +### func [RunDirectory](./run.go#L121)func RunDirectory(out OutputSettings, version string, includeMain bool) error @@ -57,7 +62,7 @@ type OutputSettings struct { Filename string }-### func (output *OutputSettings) [Writer](./run.go#L108) +### func (output *OutputSettings) [Writer](./run.go#L107)func (output *OutputSettings) Writer() (io.WriteCloser, error)diff --git a/pkg/mod.go b/pkg/mod.go index d1d06ca..c4ab3ac 100644 --- a/pkg/mod.go +++ b/pkg/mod.go @@ -3,6 +3,7 @@ package pkg import ( "bufio" "errors" + "fmt" "os" "path/filepath" "strings" @@ -10,6 +11,11 @@ import ( log "github.com/sirupsen/logrus" ) +var ( + ErrModuleNameMissing = errors.New("failed to find module name") + ErrGoModMissing = errors.New("unable to find go.mod") +) + func hasGoMod(dir string) bool { // log.Info("Checking " + dir) _, err := os.Stat(dir + "/go.mod") @@ -19,8 +25,9 @@ func hasGoMod(dir string) bool { func moduleName(dir string) (string, error) { f, err := os.Open(dir + "/go.mod") if err != nil { - log.WithFields(log.Fields{"dir": dir, "err": err}).Error("Failed to open go.mod") - return "", errors.New("failed to open go.mod") + err = fmt.Errorf("moduleName failed: %w", err) + log.WithFields(log.Fields{"dir": dir}).Error(err) + return "", err } defer f.Close() scan := bufio.NewScanner(f) @@ -35,28 +42,29 @@ func moduleName(dir string) (string, error) { log.WithFields(log.Fields{"line": line}).Error("module name missing from line") } } - return "", errors.New("failed to find module name from go.mod") + return "", fmt.Errorf("%w from %s/go.mod", ErrModuleNameMissing, dir) } // getPackageName assumes that each directory has one package name in golang namespace. func getPackageName(dir string) (string, error) { cwd, err := filepath.Abs(dir) if err != nil { - return "", errors.New("unable to determine absolute path") + return "", fmt.Errorf("getPackageName failed: %w", err) } dirs := strings.Split(cwd, "/") - for join := len(dirs); join > 0; join-- { - current := strings.Join(dirs[0:join], "/") - if hasGoMod(current) { - mod, err := moduleName(current) - if err != nil { - return "", err - } - parts := append([]string{mod}, dirs[join:]...) - return strings.Join(parts, "/"), nil + for idx := len(dirs); idx > 0; idx-- { + root := strings.Join(dirs[0:idx], "/") + if !hasGoMod(root) { + continue + } + modName, err := moduleName(root) + if err != nil { + return "", err } + parts := append([]string{modName}, dirs[idx:]...) + return strings.Join(parts, "/"), nil } - return "", errors.New("unable to find go.mod with module name") + return "", fmt.Errorf("%w from %s or its parent dirs", ErrGoModMissing, cwd) } func fileExists(fname string) bool { diff --git a/pkg/run.go b/pkg/run.go index 934337c..41b5db1 100644 --- a/pkg/run.go +++ b/pkg/run.go @@ -40,8 +40,9 @@ var ( // Markdown is golang template for go2md output // //go:embed template.md - Markdown string // value from template.md file - ErrNoPackageFound = errors.New("couldn't find package from ") + Markdown string // value from template.md file + ErrManyPackagesInDir = errors.New("can only handle one package per directory") + ErrNoPackageFound = errors.New("couldn't find package from ") ) // isProductionGo ignores all code that is only used for `go test` @@ -57,11 +58,11 @@ func getImportsFromFile(specs []*ast.ImportSpec) map[string]string { for _, spec := range specs { path := strings.Trim(spec.Path.Value, ("\"")) switch { - case spec.Name == nil: + case spec.Name == nil: // import "github.com/..." fields := strings.Split(path, "/") imported[fields[len(fields)-1]] = path - case spec.Name.Name == "_": // ignore - default: + case spec.Name.Name == "_": // ignore import _ "github.com/..." + default: // import alias "github.com/..." imported[spec.Name.Name] = path } } @@ -120,7 +121,7 @@ func (output *OutputSettings) Writer() (io.WriteCloser, error) { func RunDirectory(out OutputSettings, version string, includeMain bool) error { pkgName, err := getPackageName(out.Directory) if err != nil { - return fmt.Errorf("failed determine module name: %w", err) + return err } return run(out, pkgName, version, includeMain) } @@ -245,7 +246,7 @@ func getPackage(directory, modName string, includeMain bool) (*packageInfo, erro for _, pkg := range pkgs { names = append(names, pkg.Name) } - return nil, fmt.Errorf("can only handle one package per directory (found: %s)", strings.Join(names, ", ")) + return nil, fmt.Errorf("%w (found: %s)", ErrManyPackagesInDir, strings.Join(names, ", ")) } // Run reads all "*.go" files (excluding "*_test.go") and writes markdown document out of it.