Skip to content

Commit

Permalink
Merge pull request golang#157 from ReSTARTR/read-symlink
Browse files Browse the repository at this point in the history
Read the destination of named symbolic link
  • Loading branch information
sdboyer committed Mar 5, 2017
2 parents db8fd63 + 425722b commit 67b7104
Show file tree
Hide file tree
Showing 12 changed files with 121 additions and 3 deletions.
1 change: 1 addition & 0 deletions _testdata/src/gosimple
1 change: 1 addition & 0 deletions _testdata/src/symlinks/broken
1 change: 1 addition & 0 deletions _testdata/src/symlinks/foo/bar
7 changes: 7 additions & 0 deletions _testdata/src/symlinks/foo/foo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package foo

import "github.com/sdboyer/gps"

var (
_ = gps.Solve
)
1 change: 1 addition & 0 deletions _testdata/src/symlinks/foobar
1 change: 1 addition & 0 deletions _testdata/src/symlinks/gopkg
1 change: 1 addition & 0 deletions _testdata/src/symlinks/pkg/bar
5 changes: 5 additions & 0 deletions _testdata/src/symlinks/pkg/gopkg.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package gopkg

const (
foo = "foo"
)
12 changes: 12 additions & 0 deletions _testdata/src/symlinks/symlinks.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package symlinks

import (
gopkg "symlinks/gopkg"

"github.com/sdboyer/gps"
)

var (
_ = gps.Solve
_ = gopkg.foo
)
32 changes: 31 additions & 1 deletion analysis.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,11 @@ func ListPackages(fileRoot, importRoot string) (PackageTree, error) {
if err != nil && err != filepath.SkipDir {
return err
}
if !fi.IsDir() {

// Read the destination of named symbolic link
if fi, err := readSymlink(wp, fileRoot, fi); err != nil {
return nil
} else if !fi.IsDir() {
return nil
}

Expand Down Expand Up @@ -195,6 +199,32 @@ func ListPackages(fileRoot, importRoot string) (PackageTree, error) {
return ptree, nil
}

func readSymlink(wp, fileRoot string, fi os.FileInfo) (os.FileInfo, error) {
// read only symlink dir
if fi.IsDir() || fi.Mode()&os.ModeSymlink == 0 {
return fi, nil
}

dst, err := os.Readlink(wp)
if err != nil {
return fi, err
}

// All absolute symlinks are disqualified; if one is encountered, it should be skipped.
if filepath.IsAbs(dst) {
return fi, nil
}

// Relative symlinks pointing to somewhere outside of the root (via ..) should also be skipped.
dst, err = filepath.EvalSymlinks(wp)
if err != nil {
return fi, nil
} else if !strings.HasPrefix(dst, fileRoot) {
return fi, nil
}
return os.Lstat(dst)
}

// fillPackage full of info. Assumes p.Dir is set at a minimum
func fillPackage(p *build.Package) error {
var buildPrefix = "// +build "
Expand Down
61 changes: 59 additions & 2 deletions analysis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -466,12 +466,13 @@ func TestListPackages(t *testing.T) {
return filepath.Join(srcdir, filepath.Join(s...))
}

table := map[string]struct {
type tc struct {
fileRoot string
importRoot string
out PackageTree
err error
}{
}
table := map[string]tc{
"empty": {
fileRoot: j("empty"),
importRoot: "empty",
Expand Down Expand Up @@ -1234,6 +1235,62 @@ func TestListPackages(t *testing.T) {
},
},
}
if runtime.GOOS != "windows" {
table["follow_symlink"] = tc{
fileRoot: j("gosimple"),
importRoot: "gosimple",
out: PackageTree{
ImportRoot: "gosimple",
Packages: map[string]PackageOrErr{},
},
}
table["follow symlinks inside of package"] = tc{
fileRoot: j("symlinks"),
importRoot: "symlinks",
out: PackageTree{
ImportRoot: "symlinks",
Packages: map[string]PackageOrErr{
"symlinks/gopkg": {
P: Package{
ImportPath: "symlinks/gopkg",
CommentPath: "",
Name: "gopkg",
Imports: []string{},
},
},
"symlinks/pkg": {
P: Package{
ImportPath: "symlinks/pkg",
CommentPath: "",
Name: "gopkg",
Imports: []string{},
},
},
"symlinks": {
P: Package{
ImportPath: "symlinks",
CommentPath: "",
Name: "symlinks",
Imports: []string{
"github.com/sdboyer/gps",
"symlinks/gopkg",
},
},
},
"symlinks/foo": {
P: Package{
ImportPath: "symlinks/foo",
CommentPath: "",
Name: "foo",
Imports: []string{
"github.com/sdboyer/gps",
},
},
},
},
},
}
}

for name, fix := range table {
if _, err := os.Stat(fix.fileRoot); err != nil {
Expand Down
1 change: 1 addition & 0 deletions circle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ dependencies:
- wget https://github.com/Masterminds/glide/releases/download/0.10.1/glide-0.10.1-linux-amd64.tar.gz
- tar -vxz -C $HOME/bin --strip=1 -f glide-0.10.1-linux-amd64.tar.gz
override:
- mkdir -p $HOME/.go_workspace/src
- glide --home $HOME/.glide -y glide.yaml install --cache
- mkdir -p $RD
- rsync -azC --delete ./ $RD
Expand Down

0 comments on commit 67b7104

Please sign in to comment.