diff --git a/cmd/gomarkdoc/README.md b/cmd/gomarkdoc/README.md index ab0d964..1bff6d6 100644 --- a/cmd/gomarkdoc/README.md +++ b/cmd/gomarkdoc/README.md @@ -15,7 +15,7 @@ See https://github.com/Weborama/gomarkdoc for full documentation of this tool. - [type PackageSpec](<#type-packagespec>) -## type [PackageSpec]() +## type [PackageSpec]() PackageSpec defines the data available to the \-\-output option's template. Information is recomputed for each package generated. diff --git a/cmd/gomarkdoc/command.go b/cmd/gomarkdoc/command.go index 6bb3bad..4446015 100644 --- a/cmd/gomarkdoc/command.go +++ b/cmd/gomarkdoc/command.go @@ -18,6 +18,7 @@ import ( "github.com/spf13/cobra" "github.com/spf13/viper" + "golang.org/x/mod/modfile" "github.com/Weborama/gomarkdoc" "github.com/Weborama/gomarkdoc/format" @@ -51,6 +52,7 @@ type commandOptions struct { footer string footerFile string format string + fullPackageName string tags []string templateOverrides map[string]string templateFileOverrides map[string]string @@ -60,6 +62,7 @@ type commandOptions struct { check bool embed bool version bool + forceLocalDir bool } // Flags populated by goreleaser @@ -235,6 +238,18 @@ func buildCommand() *cobra.Command { false, "Print the version.", ) + command.Flags().StringVar( + &opts.fullPackageName, + "full-package-name", + "", + "will be used by option force-local-dir, instead read from go.mod file", + ) + command.Flags().BoolVar( + &opts.forceLocalDir, + "force-local-dir", + false, + "if true, will use the full-package-name to infer the .Dir", + ) // We ignore the errors here because they only happen if the specified flag doesn't exist _ = viper.BindPFlag("includeUnexported", command.Flags().Lookup("include-unexported")) @@ -253,6 +268,8 @@ func buildCommand() *cobra.Command { _ = viper.BindPFlag("repository.defaultBranch", command.Flags().Lookup("repository.default-branch")) _ = viper.BindPFlag("repository.path", command.Flags().Lookup("repository.path")) _ = viper.BindPFlag("forceRelativeURLs", command.Flags().Lookup("force-relative-urls")) + _ = viper.BindPFlag("fullPackageName", command.Flags().Lookup("full-package-name")) + _ = viper.BindPFlag("forceLocalDir", command.Flags().Lookup("force-local-dir")) return command } @@ -301,7 +318,10 @@ func runCommand(paths []string, opts commandOptions) error { return fmt.Errorf("gomarkdoc: invalid output template: %w", err) } - specs := getSpecs(paths...) + specs, err := getSpecs(opts, paths...) + if err != nil { + return err + } if err := resolveOutput(specs, outputTmpl); err != nil { return err @@ -467,7 +487,48 @@ func getBuildPackage(path string, tags []string) (*build.Package, error) { return pkg, nil } -func getSpecs(paths ...string) []*PackageSpec { +func getLocalDir(path, fullModule string) string { + const currDir = `.` + + if fullModule == "" { + return currDir + } + + if subpath, ok := strings.CutPrefix(path, fullModule); ok { + return currDir + subpath + } + + return currDir +} + +func getFullPackageName(opts commandOptions) (string, error) { + if !opts.forceLocalDir { + return "", nil + } + + if opts.fullPackageName != "" { + return opts.fullPackageName, nil + } + + data, err := os.ReadFile("go.mod") + if err != nil { + return "", fmt.Errorf("unable to read module file: %w", err) + } + + f, err := modfile.Parse("go.mod", data, nil) + if err != nil { + return "", fmt.Errorf("unable to parse module file: %w", err) + } + + return f.Module.Mod.String(), nil +} + +func getSpecs(opts commandOptions, paths ...string) ([]*PackageSpec, error) { + fullPackageName, err := getFullPackageName(opts) + if err != nil { + return nil, err + } + var expanded []*PackageSpec for _, path := range paths { // Ensure that the path we're working with is normalized for the OS @@ -481,7 +542,7 @@ func getSpecs(paths ...string) []*PackageSpec { if isLocal { dir = path } else { - dir = "." + dir = getLocalDir(path, fullPackageName) } expanded = append(expanded, &PackageSpec{ Dir: dir, @@ -558,7 +619,7 @@ func getSpecs(paths ...string) []*PackageSpec { } } - return expanded + return expanded, nil } var ignoredDirs = []string{".git"} diff --git a/go.mod b/go.mod index 1d6a2bc..fac5ddb 100644 --- a/go.mod +++ b/go.mod @@ -13,6 +13,7 @@ require ( github.com/spf13/cobra v1.8.1 github.com/spf13/viper v1.19.0 github.com/x-cray/logrus-prefixed-formatter v0.5.2 + golang.org/x/mod v0.21.0 mvdan.cc/xurls/v2 v2.5.0 ) diff --git a/go.sum b/go.sum index e13fe71..6c0d5eb 100644 --- a/go.sum +++ b/go.sum @@ -188,6 +188,8 @@ golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=