-
Notifications
You must be signed in to change notification settings - Fork 1k
Resolve symlinks if project root has them. #247
Changes from 8 commits
76cfb05
6c8491c
0047ea1
f41f58a
5a56a59
bbf9364
c922a91
ab79f83
4e3205d
f5c52ec
0628b80
f569ebc
382d489
c2deecc
753c8dd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ func NewContext() (*Ctx, error) { | |
// this way we get the default GOPATH that was added in 1.8 | ||
buildContext := build.Default | ||
wd, err := os.Getwd() | ||
|
||
if err != nil { | ||
return nil, errors.Wrap(err, "getting work directory") | ||
} | ||
|
@@ -75,6 +76,13 @@ func (c *Ctx) LoadProject(path string) (*Project, error) { | |
return nil, err | ||
} | ||
|
||
// the path may lie within a symlinked directory, resolve that | ||
// before moving forward | ||
p.AbsRoot, err = c.resolveProjectRoot(p.AbsRoot) | ||
if err != nil { | ||
return nil, errors.Wrapf(err, "resolve project root") | ||
} | ||
|
||
ip, err := c.SplitAbsoluteProjectRoot(p.AbsRoot) | ||
if err != nil { | ||
return nil, errors.Wrap(err, "split absolute project root") | ||
|
@@ -118,6 +126,42 @@ func (c *Ctx) LoadProject(path string) (*Project, error) { | |
return p, nil | ||
} | ||
|
||
// resolveProjectRoot evaluates the root directory and does the following: | ||
// | ||
// If the passed path is a symlink outside GOPATH to a directory within a | ||
// GOPATH, the resolved full real path is returned. | ||
// | ||
// If the passed path is a symlink within a GOPATH, we return an error. | ||
// | ||
// If the passed path isn't a symlink at all, we just pass through. | ||
func (c *Ctx) resolveProjectRoot(path string) (string, error) { | ||
// Determine if this path is a Symlink | ||
l, err := os.Lstat(path) | ||
if err != nil { | ||
return "", errors.Wrap(err, "resolveProjectRoot") | ||
} | ||
|
||
// Pass through if not | ||
if l.Mode()&os.ModeSymlink == 0 { | ||
return path, nil | ||
} | ||
|
||
// Resolve path | ||
resolved, err := filepath.EvalSymlinks(path) | ||
if err != nil { | ||
return "", errors.Wrap(err, "resolveProjectRoot") | ||
} | ||
|
||
// Determine if the symlink is within the GOPATH, in which case we're not | ||
// sure how to resolve it. | ||
if filepath.HasPrefix(path, c.GOPATH) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This search needs to be more expansive - it should check all other GOPATHs, not just the selected one (see To minimize our exposure to other globals, let's update There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Good call. 👍 On it. |
||
return "", fmt.Errorf("''%s' is linked to another path within GOPATH", path) | ||
} | ||
|
||
// Return the resolved path | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: i don't think this comment adds much |
||
return resolved, nil | ||
} | ||
|
||
// SplitAbsoluteProjectRoot takes an absolute path and compares it against declared | ||
// GOPATH(s) to determine what portion of the input path should be treated as an | ||
// import path - as a project root. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: I'm learning that go/stdlib coding standards generally look for complete sentences w/punctuation and capitalization in comments. It's also OK to have a just a couple explanatory words - but this sorta thing (a complete sentence, but lacking proper in these details) is a no-no.
(Something like that, @rakyll ? 😄 )