Gostaticanalysis Skeleton Versions Save

Tool: skeleton is create skeleton codes for golang.org/x/tools/go/analysis.

v2.2.2

1 year ago
  • Fix -gomod flag bug (#64)

v2.2.1

1 year ago
  • Improvement README
  • Go1.18 support
  • Fix a bug of -gomod flag

v2.2.0

1 year ago
  • Add gomod flag

v2.1.2

2 years ago
  • Fix main.go of packages kind tempalte

v2.1.1

2 years ago
  • Fix template for packages kind
  • Add tests which execute go test in generated directories

v2.1.0

2 years ago

Add packages kind

If you give packages to kind option, skeleton generates golang.org/x/tools/go/packages package based source codes.

$ skeleton -kind packages example
$ tree example
example
├── cmd
│   └── example
│       └── main.go
├── example.go
├── example_test.go
├── go.mod
└── testdata
    ├── a-stderr.golden
    ├── a-stdout.golden
    └── src
        └── a
            ├── a.go
            └── go.mod

The generated codes consist of main.go, analyzer-like analyzing code and a test code which check by golden file testing.

example/example.go

package example

import (
	"flag"
	"fmt"
	"go/ast"
	"io"
	"path/filepath"

	"golang.org/x/tools/go/ast/inspector"
	"golang.org/x/tools/go/packages"
)

type Pass struct {
	Pkg    *packages.Package
	Stdin  io.Reader
	Stdout io.Writer
	Stderr io.Writer
}

var Analyzer = struct {
	Name   string
	Doc    string
	Flags  *flag.FlagSet
	Config *packages.Config
	Run    func(pass *Pass) error
}{
	Name: "example",
	Doc:  "example is ...",
	Config: &packages.Config{
		Mode: packages.NeedName | packages.NeedTypes |
			packages.NeedSyntax | packages.NeedTypesInfo |
			packages.NeedModule,
	},
	Run: run,
}

func run(pass *Pass) error {
	inspect := inspector.New(pass.Pkg.Syntax)

	nodeFilter := []ast.Node{
		(*ast.Ident)(nil),
	}

	inspect.Preorder(nodeFilter, func(n ast.Node) {
		switch n := n.(type) {
		case *ast.Ident:
			if n.Name == "gopher" {
				pos := pass.Pkg.Fset.Position(n.Pos())
				fname, err := filepath.Rel(pass.Pkg.Module.Dir, pos.Filename)
				if err != nil {
					return
				}
				fmt.Fprintf(pass.Stdout, "%s:%d:%d identifier is gopher\n", fname, pos.Line, pos.Column)
			}
		}
	})

	return nil
}

example/example_test.go

package example_test

import (
	"bytes"
	"flag"
	"path/filepath"
	"strings"
	"testing"

	"example"

	"github.com/tenntenn/golden"
	"golang.org/x/tools/go/packages"
)

var (
	flagUpdate bool
)

func init() {
	flag.BoolVar(&flagUpdate, "update", false, "update golden files")
}

func Test(t *testing.T) {
	pkgs := load(t, testdata(t), "a")
	for _, pkg := range pkgs {
		run(t, pkg)
	}
}

func load(t *testing.T, testdata string, pkgname string) []*packages.Package {
	t.Helper()
	example.Analyzer.Config.Dir = filepath.Join(testdata, "src", pkgname)
	pkgs, err := packages.Load(example.Analyzer.Config, pkgname)
	if err != nil {
		t.Fatal("unexpected error:", err)
	}
	return pkgs
}

func testdata(t *testing.T) string {
	t.Helper()
	dir, err := filepath.Abs("testdata")
	if err != nil {
		t.Fatal("unexpected error:", err)
	}
	return dir
}

func run(t *testing.T, pkg *packages.Package) {
	var stdin, stdout, stderr bytes.Buffer
	pass := &example.Pass{
		Stdin:  &stdin,
		Stdout: &stdout,
		Stderr: &stderr,
		Pkg:    pkg,
	}

	if err := example.Analyzer.Run(pass); err != nil {
		t.Error("unexpected error:", err)
	}

	pkgname := pkgname(pkg)

	if flagUpdate {
		golden.Update(t, testdata(t), pkgname+"-stdout", &stdout)
		golden.Update(t, testdata(t), pkgname+"-stderr", &stderr)
		return
	}

	if diff := golden.Diff(t, testdata(t), pkgname+"-stdout", &stdout); diff != "" {
		t.Errorf("stdout of analyzing %s:\n%s", pkgname, diff)
	}

	if diff := golden.Diff(t, testdata(t), pkgname+"-stderr", &stderr); diff != "" {
		t.Errorf("stderr of analyzing %s:\n%s", pkgname, diff)
	}
}

func pkgname(pkg *packages.Package) string {
	switch {
	case pkg.PkgPath != "":
		return strings.ReplaceAll(pkg.PkgPath, "/", "-")
	case pkg.Name != "":
		return pkg.Name
	default:
		return pkg.ID
	}
}

v2.0.5

2 years ago
  • Use gostaticanalysis/skeletonkit and tenntenn/golden internally
  • Add usage of SKELETON_PREFIX environment variable

v2.0.4

2 years ago
  • Trim spaces from version

v2.0.3

2 years ago
  • Fix typo in README by @nobishino (Thanks!!)
  • Fix checker of codegen
  • Execute goimports for generated go files
  • Add workflow of test and vet

v2.0.2

2 years ago
  • Remove new line from -v