Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panic on generate #15

Closed
Posya opened this issue Mar 19, 2024 · 4 comments · Fixed by #24
Closed

Panic on generate #15

Posya opened this issue Mar 19, 2024 · 4 comments · Fixed by #24
Milestone

Comments

@Posya
Copy link

Posya commented Mar 19, 2024

Hello!

I'm trying to make documentation out of a structure
There is a config.Config structure, and nested structures in different packages

package config
//go:generate go run github.com/g4s8/envdoc@latest -output environments.md
type Config struct {
	ProgName         string `env:"PROG_NAME,notEmpty" envDefault:"prog"`
	Logger           log.Config

	Application lifecycle.Config
	RestAPI     restapi.Config
}

package log
type Config struct {
	Level    string `env:"LOG_LEVEL,notEmpty"  envDefault:"info"`
	Format   string `env:"LOG_FORMAT,notEmpty" envDefault:"json"`
}

package lifecycle
type Config struct {
	AppGracePeriod        time.Duration `env:"APP_GRACE_PERIOD,notEmpty"        envDefault:"10s"`
}

package restapi
type Config struct {
	Port         int           `env:"RESTAPI_PORT"          envDefault:"8080"`
	ReadTimeout  time.Duration `env:"RESTAPI_READ_TIMEOUT"  envDefault:"5s"`
	WriteTimeout time.Duration `env:"RESTAPI_WRITE_TIMEOUT" envDefault:"10s"`
	IdleTimeout  time.Duration `env:"RESTAPI_IDLE_TIMEOUT"  envDefault:"120s"`
}

When trying to generate an error is thrown

go generate ./internal/config/...
panic: expected type node root child, got nodeField (Config)

goroutine 1 [running]:
main.(*inspector).traverseAST(0xc0000bdc60, 0xc0000bf200, {0xc000012ad0, 0x6})
        /root/go/pkg/mod/github.com/g4s8/[email protected]/inspector.go:64 +0x445
main.(*inspector).inspectFile(0xc0000bdc60, {0xc0000120c7, 0x9})
        /root/go/pkg/mod/github.com/g4s8/[email protected]/inspector.go:51 +0x308
main.(*generator).generate(0xc00007f110, {0x60b9e8, 0xc00005aa98})
        /root/go/pkg/mod/github.com/g4s8/[email protected]/generator.go:99 +0xc6
main.run(0xc0000bde40)
        /root/go/pkg/mod/github.com/g4s8/[email protected]/main.go:133 +0x629
main.main()
        /root/go/pkg/mod/github.com/g4s8/[email protected]/main.go:70 +0x12a
exit status 2
internal/config/config.go:20: running "go": exit status 1
@g4s8
Copy link
Owner

g4s8 commented Mar 19, 2024

I've just tried your example (just removed package declarations), and it generated this environments.md file:

# Environment Variables

## Config

 - `PROG_NAME` (**required**, non-empty, default: `prog`) - 

## Config

 - `LOG_LEVEL` (**required**, non-empty, default: `info`) - 
 - `LOG_FORMAT` (**required**, non-empty, default: `json`) - 

## Config

 - `APP_GRACE_PERIOD` (**required**, non-empty, default: `10s`) - 

## Config

 - `RESTAPI_PORT` (default: `8080`) - 
 - `RESTAPI_READ_TIMEOUT` (default: `5s`) - 
 - `RESTAPI_WRITE_TIMEOUT` (default: `10s`) - 
 - `RESTAPI_IDLE_TIMEOUT` (default: `120s`) - 

Original source file:

package config

import (
	"time"

	"github.com/g4s8/go-lifecycle/pkg/lifecycle"
	"github.com/ipfs/go-log/v2"
)

//go:generate go run github.com/g4s8/envdoc@latest -output environments.md
type Config struct {
	ProgName string `env:"PROG_NAME,notEmpty" envDefault:"prog"`
	Logger   log.Config

	Application lifecycle.Config
	RestAPI     restapi.Config
}

type Config struct {
	Level  string `env:"LOG_LEVEL,notEmpty"  envDefault:"info"`
	Format string `env:"LOG_FORMAT,notEmpty" envDefault:"json"`
}

type Config struct {
	AppGracePeriod time.Duration `env:"APP_GRACE_PERIOD,notEmpty"        envDefault:"10s"`
}

type Config struct {
	Port         int           `env:"RESTAPI_PORT"          envDefault:"8080"`
	ReadTimeout  time.Duration `env:"RESTAPI_READ_TIMEOUT"  envDefault:"5s"`
	WriteTimeout time.Duration `env:"RESTAPI_WRITE_TIMEOUT" envDefault:"10s"`
	IdleTimeout  time.Duration `env:"RESTAPI_IDLE_TIMEOUT"  envDefault:"120s"`
}

Maybe you have some old cached version of envdoc?

Could you try using the latest version manually:

//go:generate go run github.com/g4s8/[email protected] -output environments.md

And please add the output of go version here.

@Posya
Copy link
Author

Posya commented Mar 20, 2024

Hello!

Could you try using the latest version manually

The same:

panic: expected type node root child, got nodeField (Config)

goroutine 1 [running]:
main.(*inspector).traverseAST(0xc00008fc60, 0xc000157200, {0xc0001209d0, 0x6})
        /root/go/pkg/mod/github.com/g4s8/[email protected]/inspector.go:64 +0x445
main.(*inspector).inspectFile(0xc00008fc60, {0xc000012107, 0x9})
        /root/go/pkg/mod/github.com/g4s8/[email protected]/inspector.go:51 +0x308
main.(*generator).generate(0xc00011d110, {0x60b9e8, 0xc00010ea90})
        /root/go/pkg/mod/github.com/g4s8/[email protected]/generator.go:99 +0xc6
main.run(0xc00008fe40)
        /root/go/pkg/mod/github.com/g4s8/[email protected]/main.go:133 +0x629
main.main()
        /root/go/pkg/mod/github.com/g4s8/[email protected]/main.go:70 +0x12a
exit status 2
internal/config/config.go:20: running "go": exit status 1

And please add the output of go version here

go version go1.22.0 linux/amd64

@Posya
Copy link
Author

Posya commented Mar 20, 2024

Ok, I got a different result:

File tree structure:

.
├── go.mod
├── go.sum
├── internal
│     ├── config
│     │     └── config.go
│     ├── lifecycle
│     │     └── l.go
│     ├── log
│     │     └── l.go
│     └── restapi
│         └── r.go
└── main.go

Files:

  • ./internal/config/config.go
package config

import (
        "tmp/internal/lifecycle"
        "tmp/internal/log"
        "tmp/internal/restapi"
)

//go:generate go run github.com/g4s8/envdoc@latest -output environments.md
type Config struct {
        ProgName string `env:"PROG_NAME,notEmpty" envDefault:"prog"`
        Logger   log.Config

        Application lifecycle.Config
        RestAPI     restapi.Config
}
  • ./internal/lifecycle/l.go
package lifecycle

import "time"

type Config struct {
        AppGracePeriod time.Duration `env:"APP_GRACE_PERIOD,notEmpty"        envDefault:"10s"`
}
  • ./internal/log/l.go
package log

type Config struct {
        Level  string `env:"LOG_LEVEL,notEmpty"  envDefault:"info"`
        Format string `env:"LOG_FORMAT,notEmpty" envDefault:"json"`
}
  • ./internal/restapi/r.go
package restapi

import "time"

type Config struct {
        Port         int           `env:"RESTAPI_PORT"          envDefault:"8080"`
        ReadTimeout  time.Duration `env:"RESTAPI_READ_TIMEOUT"  envDefault:"5s"`
        WriteTimeout time.Duration `env:"RESTAPI_WRITE_TIMEOUT" envDefault:"10s"`
        IdleTimeout  time.Duration `env:"RESTAPI_IDLE_TIMEOUT"  envDefault:"120s"`
}

MD file generation works, although the result is somewhat truncated

# Environment Variables

## Config

 - `PROG_NAME` (**required**, non-empty, default: `prog`) -

@g4s8
Copy link
Owner

g4s8 commented Mar 22, 2024

The problem here is that go generate tools with AST parsers are working with source files, not packages, so it's not possible to resolve the type from another package automatically. I see two solutions to fix that:

  • provide some kind of parameter for project root, and parse the whole project to process all types, e.g. -project-root ./../..
  • manually specify additional files to include: -include ./restapi/r.go

Need to think about better solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants