Skip to content

Commit c4febc3

Browse files
committed
Add --tag-relative flag
This allows you, in combination with the -f flag, to specify whether tag file names should be relative to the output directory.
1 parent dd6fc3d commit c4febc3

File tree

5 files changed

+40
-12
lines changed

5 files changed

+40
-12
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ gotags is a [ctags][]-compatible tag generator for [Go][].
2020
-f="": write output to specified file. If file is "-", output is written to standard out.
2121
-silent=false: do not produce any output on error.
2222
-sort=true: sort tags.
23+
-tag-relative=false: file paths should be relative to the directory containing the tag file.
2324
-v=false: print version.
2425

2526
## Vim [Tagbar][] configuration

main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"fmt"
77
"io"
88
"os"
9+
"path"
910
"path/filepath"
1011
"sort"
1112
"strings"
@@ -27,6 +28,7 @@ var (
2728
recurse bool
2829
sortOutput bool
2930
silent bool
31+
relative bool
3032
)
3133

3234
// Initialize flags.
@@ -37,6 +39,7 @@ func init() {
3739
flag.BoolVar(&recurse, "R", false, "recurse into directories in the file list.")
3840
flag.BoolVar(&sortOutput, "sort", true, "sort tags.")
3941
flag.BoolVar(&silent, "silent", false, "do not produce any output on error.")
42+
flag.BoolVar(&relative, "tag-relative", false, "file paths should be relative to the directory containing the tag file.")
4043

4144
flag.Usage = func() {
4245
fmt.Fprintf(os.Stderr, "gotags version %s\n\n", Version)
@@ -145,7 +148,7 @@ func main() {
145148

146149
tags := []Tag{}
147150
for _, file := range files {
148-
ts, err := Parse(file)
151+
ts, err := Parse(file, relative, path.Dir(outputFile))
149152
if err != nil {
150153
if !silent {
151154
fmt.Fprintf(os.Stderr, "parse error: %s\n\n", err)

parser.go

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,29 @@ import (
55
"go/ast"
66
"go/parser"
77
"go/token"
8+
"os"
9+
"path/filepath"
810
"strings"
911
)
1012

1113
// tagParser contains the data needed while parsing.
1214
type tagParser struct {
13-
fset *token.FileSet
14-
tags []Tag // list of created tags
15-
types []string // all types we encounter, used to determine the constructors
15+
fset *token.FileSet
16+
tags []Tag // list of created tags
17+
types []string // all types we encounter, used to determine the constructors
18+
relative bool // should filenames be relative to basepath
19+
basepath string // output file directory
1620
}
1721

18-
// Parse parses the source in filename and returns a list of tags.
19-
func Parse(filename string) ([]Tag, error) {
22+
// Parse parses the source in filename and returns a list of tags. If relative
23+
// is true, the filenames in the list of tags are relative to basepath.
24+
func Parse(filename string, relative bool, basepath string) ([]Tag, error) {
2025
p := &tagParser{
21-
fset: token.NewFileSet(),
22-
tags: []Tag{},
23-
types: make([]string, 0),
26+
fset: token.NewFileSet(),
27+
tags: []Tag{},
28+
types: make([]string, 0),
29+
relative: relative,
30+
basepath: basepath,
2431
}
2532

2633
f, err := parser.ParseFile(p.fset, filename, nil, 0)
@@ -199,7 +206,16 @@ func (p *tagParser) parseInterfaceMethods(name string, s *ast.InterfaceType) {
199206

200207
// createTag creates a new tag, using pos to find the filename and set the line number.
201208
func (p *tagParser) createTag(name string, pos token.Pos, tagType TagType) Tag {
202-
return NewTag(name, p.fset.File(pos).Name(), p.fset.Position(pos).Line, tagType)
209+
f := p.fset.File(pos).Name()
210+
if p.relative {
211+
if rel, err := filepath.Rel(p.basepath, f); err != nil {
212+
// log error, but continue
213+
fmt.Fprintf(os.Stderr, "could not determine relative path: %s\n", err)
214+
} else {
215+
f = rel
216+
}
217+
}
218+
return NewTag(name, f, p.fset.Position(pos).Line, tagType)
203219
}
204220

205221
// belongsToReceiver checks if a function with these return types belongs to

parser_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ type F map[TagField]string
99

1010
var testCases = []struct {
1111
filename string
12+
relative bool
13+
basepath string
1214
tags []Tag
1315
}{
1416
{filename: "tests/const.go-src", tags: []Tag{
@@ -82,11 +84,14 @@ var testCases = []struct {
8284
tag("C", 8, "v", F{"access": "public"}),
8385
tag("D", 9, "v", F{"access": "public"}),
8486
}},
87+
{filename: "tests/simple.go-src", relative: true, basepath: "dir", tags: []Tag{
88+
Tag{Name: "main", File: "../tests/simple.go-src", Address: "1", Type: "p", Fields: F{"line": "1"}},
89+
}},
8590
}
8691

8792
func TestParse(t *testing.T) {
8893
for _, testCase := range testCases {
89-
tags, err := Parse(testCase.filename)
94+
tags, err := Parse(testCase.filename, testCase.relative, testCase.basepath)
9095
if err != nil {
9196
t.Errorf("[%s] Parse error: %s", testCase.filename, err)
9297
continue
@@ -98,7 +103,9 @@ func TestParse(t *testing.T) {
98103
}
99104

100105
for i, tag := range testCase.tags {
101-
tag.File = testCase.filename
106+
if len(tag.File) == 0 {
107+
tag.File = testCase.filename
108+
}
102109
if tags[i].String() != tag.String() {
103110
t.Errorf("[%s] tag(%d)\n is:%s\nwant:%s", testCase.filename, i, tags[i].String(), tag.String())
104111
}

tests/simple.go-src

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
package main

0 commit comments

Comments
 (0)