Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

x/tools/go/vcs: FromDir documentation and root return value #7723

Closed
kr opened this issue Apr 7, 2014 · 10 comments
Closed

x/tools/go/vcs: FromDir documentation and root return value #7723

kr opened this issue Apr 7, 2014 · 10 comments

Comments

@kr
Copy link
Contributor

kr commented Apr 7, 2014

func FromDir(dir, srcRoot string) (vcs *Cmd, root string, err error)

"FromDir inspects dir and its parents to determine the version control
system and code repository to use. On return, root is the import path
corresponding to the root of the repository (thus root is a prefix of
importPath)."

- importPath isn't part of the function's signature. Copy-paste error
from somewhere?

- the value returned in root starts with "src/"; it is not a prefix of
any typical import path. Doc bug or code bug?

- the returned root is a filesystem path, but documenting it as an
"import path" suggests it'll always be slash-separated.
Doc bug or code bug?
@robpike
Copy link
Contributor

robpike commented Apr 7, 2014

Comment 1:

Easy doc fix. Should do for 1.3

Labels changed: added release-go1.3, repo-tools.

Owner changed to @robpike.

Status changed to Accepted.

@kr
Copy link
Contributor Author

kr commented Apr 7, 2014

Comment 2:

I think part of this confusion is from me misunderstanding the purpose of srcRoot. I had
been using the Root field from 'go list' directly, but it looks like it should be
filepath.Join(pkg.Root, "src")

@rsc
Copy link
Contributor

rsc commented Apr 22, 2014

Comment 3:

Not part of the release.

Labels changed: removed release-go1.3.

@paranoiacblack
Copy link
Contributor

Comment 5:

I have a couple of follow-up questions, to make sure I get this right.  The `importPath`
comment is erroneous as you state, but I'm wondering if you could provide some context
about the other two points you make.  Perhaps an example of a directory layout for a
given repository and a mismatch between what you expect from FromDir and what it returns
instead.
"- the returned root is a filesystem path, but documenting it as an
"import path" suggests it'll always be slash-separated.
Doc bug or code bug?"
Can you clarify this, as well?  What was the import path separated by if not by slashes?

@kr
Copy link
Contributor Author

kr commented Apr 25, 2014

Comment 6:

On Windows, the root parameter contains backslashes.
But an import path is conventionally slash-separated,
not a filepath as implemented here. (It's a slice of dir.)
My middle point above was due to my confusion about
what to provide for srcRoot. For a dir of $GOPATH/src/foo/bar,
I had been providing $GOPATH and getting back src/foo.
Providing $GOPATH/src yields just foo, as documented.
A sentence documenting the expected form of srcRoot would
have saved me a little time.

@rsc
Copy link
Contributor

rsc commented May 21, 2014

Comment 7:

Labels changed: added release-none.

@rsc rsc added this to the Unplanned milestone Apr 10, 2015
@rsc rsc changed the title go.tools/go/vcs: FromDir documentation and root return value x/tools/go/vcs: FromDir documentation and root return value Apr 14, 2015
@rsc rsc modified the milestones: Unreleased, Unplanned Apr 14, 2015
@rsc rsc removed the repo-tools label Apr 14, 2015
@robpike robpike removed their assignment Aug 5, 2015
@dmitshur
Copy link
Contributor

dmitshur commented Jan 8, 2016

I also ran into the invalid root value on Windows bug and was going to file an issue, but I found this existing one.

I think part of this confusion is from me misunderstanding the purpose of srcRoot. I had
been using the Root field from 'go list' directly, but it looks like it should be
filepath.Join(pkg.Root, "src")

It should be pkg.SrcRoot, which is already set to that value. /cc @kr

  • importPath isn't part of the function's signature. Copy-paste error
    from somewhere?

You're right, importPath is confusing because it makes it sound like a variable, but there is no such variable anywhere. Perhaps it meant to say "thus root is a prefix of import path", meaning root is a prefix of the import path of the package that is in in dir.

On Windows, the root parameter contains backslashes.
But an import path is conventionally slash-separated,
not a filepath as implemented here. (It's a slice of dir.)

I can confirm, and I think it's a bug. Here's the rationale. The documentation says:

On return, root is the import path corresponding to the root of the repository

If I understand correctly, an import path is defined as a /-separated path (source here).

However, as @kr said, on Windows, there's a bug in that the returned root value uses \ as separators.

Consider this snippet being executed on Windows:

pkg, err := build.Import("example.com/repo/subpackage", "", build.FindOnly)
if err != nil {
    panic(err)
}
_, root, err := FromDir(pkg.Dir, pkg.SrcRoot)
if err != nil {
    panic(err)
}
fmt.Println(root)

On Windows, that snippet will print example.com\repo, which is incorrect (it is not an import path corresponding to repo root, it has a wrong \ character). On OS X and Linux it will print example.com/repo correctly.

The fix is simple:

diff --git a/go/vcs/vcs.go b/go/vcs/vcs.go
index a702496..b615508 100644
--- a/go/vcs/vcs.go
+++ b/go/vcs/vcs.go
@@ -348,7 +348,7 @@ func FromDir(dir, srcRoot string) (vcs *Cmd, root string, err error) {
    for len(dir) > len(srcRoot) {
        for _, vcs := range vcsList {
            if fi, err := os.Stat(filepath.Join(dir, "."+vcs.Cmd)); err == nil && fi.IsDir() {
-               return vcs, dir[len(srcRoot)+1:], nil
+               return vcs, filepath.ToSlash(dir[len(srcRoot)+1:]), nil
            }
        }

I can make a CL that fixes this issue.

@dmitshur
Copy link
Contributor

dmitshur commented Jan 9, 2016

I've created https://golang.org/cl/18461 that resolves this issue.

@gopherbot
Copy link

CL https://golang.org/cl/18461 mentions this issue.

@gopherbot
Copy link

CL https://golang.org/cl/21345 mentions this issue.

gopherbot pushed a commit that referenced this issue Apr 12, 2016
Apply golang/tools@5804fef.

In the context of cmd/go build tool, import path is a '/'-separated path.
This can be inferred from `go help importpath` and `go help packages`.
vcsFromDir documentation says on return, root is the import path
corresponding to the root of the repository. On Windows and other
OSes where os.PathSeparator is not '/', that wasn't true since root
would contain characters other than '/', and therefore it wasn't a
valid import path corresponding to the root of the repository.
Fix that by using filepath.ToSlash.

Add test coverage for vcsFromDir, it was previously not tested.
It's taken from golang.org/x/tools/go/vcs tests, and modified to
improve style.

Additionally, remove an unneccessary statement from the documentation
"(thus root is a prefix of importPath)". There is no variable
importPath that is being referred to (it's possible p.ImportPath
was being referred to). Without it, the description of root value
matches the documentation of repoRoot.root struct field:

	// root is the import path corresponding to the root of the
	// repository
	root string

Rename and change signature of vcsForDir(p *Package) to
vcsFromDir(dir, srcRoot string). This is more in sync with the x/tools
version. It's also simpler, since vcsFromDir only needs those two
values from Package, and nothing more. Change "for" to "from" in name
because it's more consistent and clear.

Update usage of vcsFromDir to match the new signature, and respect
that returned root is a '/'-separated path rather than a os.PathSeparator
separated path.

Fixes #15040.
Updates #7723.
Helps #11490.

Change-Id: Idf51b9239f57248739daaa200aa1c6e633cb5f7f
Reviewed-on: https://go-review.googlesource.com/21345
Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
Run-TryBot: Alex Brainman <alex.brainman@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
@golang golang locked and limited conversation to collaborators Mar 31, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants