~sircmpwn/annotatego

1a4debd8508a3334e3db296dd3cc77d9347fa718 — Drew DeVault 1 year, 1 month ago 453e8b0
Add getopt options
3 files changed, 79 insertions(+), 10 deletions(-)

M go.mod
M go.sum
M main.go
M go.mod => go.mod +4 -1
@@ 2,4 2,7 @@ module git.sr.ht/~sircmpwn/annotatego

go 1.12

require golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db
require (
	git.sr.ht/~sircmpwn/getopt v0.0.0-20190621174457-292febf82fd0
	golang.org/x/tools v0.0.0-20190706070813-72ffa07ba3db
)

M go.sum => go.sum +6 -0
@@ 1,3 1,9 @@
git.sr.ht/~sircmpwn/getopt v0.0.0-20190621174457-292febf82fd0 h1:gUeOEsT0mhoCKxKYJk8HeYtUZME686xs70eG2l80W5U=
git.sr.ht/~sircmpwn/getopt v0.0.0-20190621174457-292febf82fd0/go.mod h1:wMEGFFFNuPos7vHmWXfszqImLppbc0wEhh6JBfJIUgw=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=

M main.go => main.go +69 -9
@@ 12,6 12,8 @@ import (
	"os"
	"os/exec"
	"strings"

	"git.sr.ht/~sircmpwn/getopt"
)

var cwd string


@@ 27,6 29,7 @@ type LinkAnnotation struct {
	Len    int     `json:"len"`
	To     string  `json:"to"`
	Title  *string `json:"title,omitempty"`
	Color  *string `json:"color,omitempty"`
}

type MarkdownAnnotation struct {


@@ 82,11 85,48 @@ func crawlGitTree() map[string]string {
	return m
}

func godocUrl(object types.Object) string {
	var receiver string
	pkg := object.Pkg()
	if sig, ok := object.Type().(*types.Signature); ok {
		if recv := sig.Recv(); recv != nil {
			if ptr, ok := recv.Type().(*types.Pointer); ok {
				if n, ok := ptr.Elem().(*types.Named); ok {
					receiver = n.Obj().Name()
				}
			} else if n, ok := recv.Type().(*types.Named); ok {
				receiver = n.Obj().Name()
			}
		}
	}
	if receiver != "" {
		return fmt.Sprintf("https://godoc.org/%s#%s.%s",
			pkg.Path(), receiver, object.Name())
	}
	return fmt.Sprintf("https://godoc.org/%s#%s", pkg.Path(), object.Name())
}

func main() {
	var (
		disableGodoc bool
		enableTests  bool
		enableVars   bool
	)
	getopt.BoolVar(&enableVars, "-v", false,
		"Enables linking of variables to their declarations")
	getopt.BoolVar(&disableGodoc, "-d", false,
		"Disables linking to external symbols via Godoc")
	getopt.BoolVar(&enableTests, "-T", false,
		"Enables scanning of test files as well as normal code")
	err := getopt.Parse()
	if err != nil {
		log.Fatalf("getopt: ", err)
	}

	log.SetFlags(0)
	fset := token.NewFileSet()
	conf := packages.Config{
		// TODO: Configure other opts through command line
		Tests: enableTests,
		Fset: fset,
		Mode: (packages.NeedName |
			packages.NeedSyntax |


@@ 96,9 136,9 @@ func main() {
			packages.NeedDeps |
			packages.NeedImports),
	}
	pkgs, err := packages.Load(&conf, os.Args[1:]...)
	pkgs, err := packages.Load(&conf, getopt.Args()...)
	if err != nil {
		panic(err)
		log.Fatal(err)
	}
	tree := crawlGitTree()
	annotations := make(map[string][]interface{})


@@ 113,15 153,14 @@ func main() {
			}
			length := ident.End() - ident.Pos()
			filename = normalizePath(filename)
			if tree != nil {
				var ok bool
				if filename, ok = tree[filename]; !ok {
					continue
				}
			var ok bool
			if filename, ok = tree[filename]; !ok {
				continue
			}
			var (
				to    string
				color string
				title string
				to    string
			)
			switch object := object.(type) {
			case *types.Func:


@@ 136,7 175,25 @@ func main() {
					path := normalizePath(fpos.Filename)
					to = fmt.Sprintf("%s#L%d", path, fpos.Line)
					title = object.FullName()
				} else if object.Pkg() != nil && !disableGodoc {
					to = godocUrl(object)
					title = object.FullName() + " on Godoc"
				}
			case *types.Var:
				if !enableVars {
					break
				}
				tpos := fset.Position(object.Pos())
				if tpos.IsValid() && strings.HasPrefix(tpos.Filename, cwd) {
					/* Internal reference */
					path := normalizePath(tpos.Filename)
					to = fmt.Sprintf("%s#L%d", path, tpos.Line)
					title = object.Name()
				} else if object.Pkg() != nil && !disableGodoc {
					to = godocUrl(object)
					title = object.Name() + " on Godoc"
				}
				color = "transparent"
			}
			if to != "" {
				if _, ok := annotations[filename]; !ok {


@@ 152,6 209,9 @@ func main() {
				if title != "" {
					anno.Title = &title
				}
				if color != "" {
					anno.Color = &color
				}
				annotations[filename] = append(annotations[filename], anno)
			}
		}