Skip to content

Commit

Permalink
feat(cmd): add --exclude-dirs option (#101)
Browse files Browse the repository at this point in the history
  • Loading branch information
princjef authored Jun 17, 2023
1 parent f8aab49 commit e62c5ab
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 8 deletions.
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ Flags:
-c, --check Check the output to see if it matches the generated documentation. --output must be specified to use this.
--config string File from which to load configuration (default: .gomarkdoc.yml)
-e, --embed Embed documentation into existing markdown files if available, otherwise append to file.
--exclude-dirs strings List of package directories to ignore when producing documentation.
--footer string Additional content to inject at the end of each output file.
--footer-file string File containing additional content to inject at the end of each output file.
-f, --format string Format to use for writing output data. Valid options: github (default), azure-devops, plain (default "github")
Expand Down Expand Up @@ -68,6 +69,14 @@ gomarkdoc --output doc.md .

The gomarkdoc tool supports generating documentation for both local packages and remote ones. To specify a local package, start the name of the package with a period \(.\) or specify an absolute path on the filesystem. All other package signifiers are assumed to be remote packages. You may specify both local and remote packages in the same command invocation as separate arguments.

If you have a project with many packages but you want to skip documentation generation for some, you can use the \-\-exclude\-dirs option. This will remove any matching directories from the list of directories to process. Excluded directories are specified using the same pathing syntax as the packages to process. Multiple expressions may be comma\-separated or specified by using the \-\-exclude\-dirs flag multiple times.

For example, in this repository we generate documentation for the entire project while excluding our test packages by running:

```
gomarkdoc --exclude-dirs ./testData/... ./...
```

### Output Redirection

By default, the documentation generated by the gomarkdoc command is sent to standard output, where it can be redirected to a file. This can be useful if you want to perform additional modifications to the documentation or send it somewhere other than a file. However, keep in mind that there are some inconsistencies in how various shells/platforms handle redirected command output \(for example, Powershell encodes in UTF\-16, not UTF\-8\). As a result, the \-\-output option described below is recommended for most use cases.
Expand Down
54 changes: 53 additions & 1 deletion cmd/gomarkdoc/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ type commandOptions struct {
footerFile string
format string
tags []string
excludeDirs []string
templateOverrides map[string]string
templateFileOverrides map[string]string
verbosity int
Expand Down Expand Up @@ -96,6 +97,7 @@ func buildCommand() *cobra.Command {
opts.footer = viper.GetString("footer")
opts.footerFile = viper.GetString("footerFile")
opts.tags = viper.GetStringSlice("tags")
opts.excludeDirs = viper.GetStringSlice("excludeDirs")
opts.repository.Remote = viper.GetString("repository.url")
opts.repository.DefaultBranch = viper.GetString("repository.defaultBranch")
opts.repository.PathFromRoot = viper.GetString("repository.path")
Expand Down Expand Up @@ -197,6 +199,12 @@ func buildCommand() *cobra.Command {
defaultTags(),
"Set of build tags to apply when choosing which files to include for documentation generation.",
)
command.Flags().StringSliceVar(
&opts.excludeDirs,
"exclude-dirs",
nil,
"List of package directories to ignore when producing documentation.",
)
command.Flags().CountVarP(
&opts.verbosity,
"verbose",
Expand Down Expand Up @@ -241,6 +249,7 @@ func buildCommand() *cobra.Command {
_ = viper.BindPFlag("footer", command.Flags().Lookup("footer"))
_ = viper.BindPFlag("footerFile", command.Flags().Lookup("footer-file"))
_ = viper.BindPFlag("tags", command.Flags().Lookup("tags"))
_ = viper.BindPFlag("excludeDirs", command.Flags().Lookup("exclude-dirs"))
_ = viper.BindPFlag("repository.url", command.Flags().Lookup("repository.url"))
_ = viper.BindPFlag("repository.defaultBranch", command.Flags().Lookup("repository.default-branch"))
_ = viper.BindPFlag("repository.path", command.Flags().Lookup("repository.path"))
Expand Down Expand Up @@ -294,6 +303,13 @@ func runCommand(paths []string, opts commandOptions) error {

specs := getSpecs(paths...)

excluded := getSpecs(opts.excludeDirs...)
if err := validateExcludes(excluded); err != nil {
return err
}

specs = removeExcludes(specs, excluded)

if err := resolveOutput(specs, outputTmpl); err != nil {
return err
}
Expand Down Expand Up @@ -565,13 +581,49 @@ func isIgnoredDir(dirname string) bool {
return false
}

// validateExcludes checks that the exclude dirs are all directories, not
// packages.
func validateExcludes(specs []*PackageSpec) error {
for _, s := range specs {
if !s.isLocal {
return fmt.Errorf("gomarkdoc: invalid directory specified as an exclude directory: %s", s.ImportPath)
}
}

return nil
}

// removeExcludes removes any package specs that were specified as excluded.
func removeExcludes(specs []*PackageSpec, excludes []*PackageSpec) []*PackageSpec {
out := make([]*PackageSpec, 0, len(specs))
for _, s := range specs {
var exclude bool
for _, e := range excludes {
if !s.isLocal || !e.isLocal {
continue
}

if r, err := filepath.Rel(s.Dir, e.Dir); err == nil && r == "." {
exclude = true
break
}
}

if !exclude {
out = append(out, s)
}
}

return out
}

const (
cwdPathPrefix = "." + string(os.PathSeparator)
parentPathPrefix = ".." + string(os.PathSeparator)
)

func isLocalPath(path string) bool {
return strings.HasPrefix(path, cwdPathPrefix) || strings.HasPrefix(path, parentPathPrefix) || filepath.IsAbs(path)
return strings.HasPrefix(path, ".") || strings.HasPrefix(path, parentPathPrefix) || filepath.IsAbs(path)
}

func compare(r1, r2 io.Reader) (bool, error) {
Expand Down
13 changes: 13 additions & 0 deletions doc.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
// -c, --check Check the output to see if it matches the generated documentation. --output must be specified to use this.
// --config string File from which to load configuration (default: .gomarkdoc.yml)
// -e, --embed Embed documentation into existing markdown files if available, otherwise append to file.
// --exclude-dirs strings List of package directories to ignore when producing documentation.
// --footer string Additional content to inject at the end of each output file.
// --footer-file string File containing additional content to inject at the end of each output file.
// -f, --format string Format to use for writing output data. Valid options: github (default), azure-devops, plain (default "github")
Expand Down Expand Up @@ -61,6 +62,18 @@
// local and remote packages in the same command invocation as separate
// arguments.
//
// If you have a project with many packages but you want to skip documentation
// generation for some, you can use the --exclude-dirs option. This will remove
// any matching directories from the list of directories to process. Excluded
// directories are specified using the same pathing syntax as the packages to
// process. Multiple expressions may be comma-separated or specified by using
// the --exclude-dirs flag multiple times.
//
// For example, in this repository we generate documentation for the entire
// project while excluding our test packages by running:
//
// gomarkdoc --exclude-dirs ./testData/... ./...
//
// # Output Redirection
//
// By default, the documentation generated by the gomarkdoc command is sent to
Expand Down
85 changes: 85 additions & 0 deletions logger/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
<!-- Code generated by gomarkdoc. DO NOT EDIT -->

# logger

```go
import "github.com/princjef/gomarkdoc/logger"
```

Package logger provides a simple console logger for reporting information about execution to stderr.

## Index

- [type Level](<#Level>)
- [type Logger](<#Logger>)
- [func New\(level Level, opts ...Option\) Logger](<#New>)
- [type Option](<#Option>)
- [func WithField\(key string, value interface\{\}\) Option](<#WithField>)


<a name="Level"></a>
## type [Level](<https://github.com/princjef/gomarkdoc/blob/master/logger/logger.go#L24>)

Level defines valid logging levels for a Logger.

```go
type Level int
```

<a name="DebugLevel"></a>Valid logging levels

```go
const (
DebugLevel Level = iota + 1
InfoLevel
WarnLevel
ErrorLevel
)
```

<a name="Logger"></a>
## type [Logger](<https://github.com/princjef/gomarkdoc/blob/master/logger/logger.go#L12-L21>)

Logger provides basic logging capabilities at different logging levels.

```go
type Logger interface {
Debug(a ...interface{})
Debugf(format string, a ...interface{})
Info(a ...interface{})
Infof(format string, a ...interface{})
Warn(a ...interface{})
Warnf(format string, a ...interface{})
Error(a ...interface{})
Errorf(format string, a ...interface{})
}
```

<a name="New"></a>
### func [New](<https://github.com/princjef/gomarkdoc/blob/master/logger/logger.go#L44>)

```go
func New(level Level, opts ...Option) Logger
```

New initializes a new Logger.

<a name="Option"></a>
## type [Option](<https://github.com/princjef/gomarkdoc/blob/master/logger/logger.go#L27>)

Option defines an option for configuring the logger.

```go
type Option func(opts *options)
```

<a name="WithField"></a>
### func [WithField](<https://github.com/princjef/gomarkdoc/blob/master/logger/logger.go#L83>)

```go
func WithField(key string, value interface{}) Option
```

WithField sets the provided key/value pair for use on all logs.

Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)
10 changes: 3 additions & 7 deletions magefile.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func Lint() error {
return err
}

return linter.Command(`run`).Run()
return linter.Command(`run --timeout 5m`).Run()
}

func Generate() error {
Expand All @@ -36,18 +36,14 @@ func Build() error {
func Doc() error {
return shellcmd.RunAll(
`go run ./cmd/gomarkdoc .`,
`go run ./cmd/gomarkdoc --header "" ./lang/...`,
`go run ./cmd/gomarkdoc --header "" ./format/...`,
`go run ./cmd/gomarkdoc --header "" ./cmd/...`,
`go run ./cmd/gomarkdoc --header "" --exclude-dirs . --exclude-dirs ./testData/... ./...`,
)
}

func DocVerify() error {
return shellcmd.RunAll(
`go run ./cmd/gomarkdoc -c .`,
`go run ./cmd/gomarkdoc -c --header "" ./lang/...`,
`go run ./cmd/gomarkdoc -c --header "" ./format/...`,
`go run ./cmd/gomarkdoc -c --header "" ./cmd/...`,
`go run ./cmd/gomarkdoc -c --header "" --exclude-dirs . --exclude-dirs ./testData/... ./...`,
)
}

Expand Down

0 comments on commit e62c5ab

Please sign in to comment.