-
Notifications
You must be signed in to change notification settings - Fork 1k
Conversation
Thanks for your pull request. It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA). 📝 Please visit https://cla.developers.google.com/ to sign. Once you've signed, please reply here (e.g.
|
I signed it! |
CLAs look good, thanks! |
Hm. I rebased to clean up my commits and now I'm blocked on the CLA check again. edit: Looks like the CLA check is just a bit laggy right now. Lots of other open PRs pending a CLA check. |
Switched to only blessed repositories for the unit tests, as well as added an integration test (thanks @carolynvs !) |
Hmm. Both this PR and my other one #829 are waiting on the cla/google check since Friday.. |
would be great if we could get a review from @davecheney on this - marking him as a reviewer 🙏 |
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.
Yay, this is so close! I have just a few minor nits and questions.
cmd/dep/gb_importer.go
Outdated
// load the gb manifest | ||
func (i *gbImporter) load(projectDir string) error { | ||
i.logger.Println("Detected gb manifest file...") | ||
var err error |
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.
small nit: It would help to have err
defined closer to its assignment, in this case next to where 'buf' is declared.
cmd/dep/gb_importer.go
Outdated
|
||
// See if we can get a version from that constraint | ||
version, err := lookupVersionForLockedProject(pc.Ident, revision, revision, i.sm) | ||
if err != nil { |
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.
The other importers treat being unable to determine whether the revision is tagged, or the tip of a branch, as a warning and do this:
if err != nil {
// Only warn about the problem, it is not enough to warrant failing
g.logger.Println(err.Error())
}
cmd/dep/gb_importer.go
Outdated
lp = gps.NewLockedProject(pc.Ident, version, nil) | ||
|
||
fb.NewLockedProjectFeedback(lp, fb.DepTypeImported).LogFeedback(i.logger) | ||
fb.NewConstraintFeedback(pc, fb.DepTypeImported).LogFeedback(i.logger) |
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.
The convention is to log the (general) constraint first, and then the (specific) lock, giving us output that looks like this:
Using master as initial constraint for imported dep github.com/golang/lint
Trying master (cb00e56) as initial lock for imported dep github.com/golang/lint
cmd/dep/gb_importer.go
Outdated
var revision = gps.Revision(pkg.Revision) | ||
|
||
// See if we can get a version from that constraint | ||
version, err := lookupVersionForLockedProject(pc.Ident, revision, revision, i.sm) |
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.
The second parameter c gps.Constraint
should be nil
, instead of passing in the revision again.
The purpose of the constraint parameter is to help pick the appropriate tag when a revision has multiple tags, by filtering with the semver constraint from the manifest (which we don't have with gb). To be clear, it doesn't cause the function to fail, but we know that since it's a revision, it's never going to help in that case. 😀
cmd/dep/testdata/gb/golden.txt
Outdated
@@ -0,0 +1,6 @@ | |||
Detected gb manifest file... | |||
Converting from gb manifest... | |||
Trying master (a0196ba) as initial lock for imported dep github.com/sdboyer/deptestdos |
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.
As noted above, we would like to be consistent in how these are logged and have the constraints listed before the locked projects.
cmd/dep/gb_importer.go
Outdated
|
||
// gbManifest represents the manifest file for GB projects | ||
type gbManifest struct { | ||
Version int `json:"version"` |
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.
Is this used anywhere?
// Branch may be HEAD or an actual branch. In the case of HEAD, that means | ||
// the user vendored a dependency by specifying a tag or a specific revision | ||
// which results in a detached HEAD | ||
Branch string `json:"branch"` |
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.
It doesn't look like Branch is being used. If it's set to a real branch name that we can find in the repo, should it be used as the constraint in the manifest?
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.
I added support for using the branch as the initial constraint (if it's not HEAD); but I don't have a solid repository to use in the tests. Ideally there'd be a blessed test repository with two branches, then I can have a test that pins to a revision that is not on the master branch.
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.
Would https://github.com/carolynvs/deptest work for your test? It has a master and v2 branch, and it's "blessed" for using in dep's tests.
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.
I'll add a test that uses it and see how the tooling responds. Thanks.
cmd/dep/gb_importer.go
Outdated
// Path is used when the actual used package exists in a subpath | ||
// For importing purposes, this isn't necessary as dep will figure | ||
// out which packages are actually being used during resolving | ||
Path string `json:"path,omitempty"` |
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.
Since we are ignoring Path
, and don't print a warning about the fact that we ignore it, we can just remove it. 😄
version = "1.0.0" | ||
|
||
[[constraint]] | ||
branch = "master" |
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.
Right now, we are seeing "branch = master" here because the revision is the tip of master (which lookupVersionForLockedProject
identifies). I am thinking that if the revision wasn't the tip however, we'd still like the constraint to be master. If we end up adding logic for using the branch from gb, using an earlier revision from master would be one way to test that out.
how are we doing with this? |
@sdboyer @carolynvs Thanks for the feedback; been really busy now that I'm back at the office but I'll take a stab at addressing the comments once I get a chance. |
@carolynvs @sdboyer I just pushed a handful of commits that should address all of the feedback. Good call on using a non-tip revision of deptestdos, the test is much better now. |
Rebased to a single commit with all PR feedback addressed. |
cmd/dep/gb_importer.go
Outdated
// But if the branch field is not "HEAD", we can use that as the initial constraint | ||
var constraint gps.Constraint | ||
if pkg.Branch != "HEAD" { | ||
constraint = gps.NewBranch(pkg.Branch) |
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.
This method is missing a conditional branch that uses the constraint if a branch is set, and otherwise uses the result of sm.InferConstraint
. Right now, constraint is set to master, then immediately discarded a few lines down.
Here are the steps we need:
- Default the constraint to the branch if possible.
- Use that constraint to lookup the version to put in the lock.
- If the constraint is empty, try to infer it from the locked version.
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.
Ah, I misunderstood some of the functions I was calling. I'll rejigger it.
cmd/dep/testdata/gb/golden.txt
Outdated
@@ -0,0 +1,6 @@ | |||
Detected gb manifest file... | |||
Converting from gb manifest... | |||
Using ^2.0.0 as initial constraint for imported dep github.com/sdboyer/deptestdos |
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.
Once the constraint logic is fixed, this will change to Using master as initial constraint
.
cmd/dep/gb_importer.go
Outdated
if err != nil { | ||
return nil, nil, err | ||
} | ||
manifest.Constraints[pc.Ident.ProjectRoot] = gps.ProjectProperties{Source: pc.Ident.Source, Constraint: pc.Constraint} |
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.
In the gb manifest file, is it possible that the import path is a sub-package? e.g. the manifest has an entry for for "github.com/pkg/foo/cats" and "github.com/pkg/foo/dogs".
If so, then your importer will need to check if the root project has already been added, and skip subsequent imports for the same root package. For a reference, see how the godep importer handles this scenario.
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.
Yes, I believe that the gb manifest has a "importpath" which contains a subpackage, and then the combination of "repository" and "path" points to the source for that specific subpackage. I dropped the path in the importer because dep will handle that already; and I misunderstood gps.ProjectIdentifier
. I'll check the godep importer.
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.
I dorked this up for the glide importer, just opened #898 to fix. 😊
Just wanted to give a huge 👍 to @carolynvs for being so thorough in the reviews. dep is a bit of a beast, and there are plenty of opportunities to misconstrue the architecture in an importer so having such a thorough maintainer for the subsystem is a huge help. Thanks again! |
@avidal you are correct, @carolynvs is awesome 😄 thank you for sticking with it! there's obviously a lot of change in dep right now, which has definitely undermined our ability to generate good documentation - and what documentation we have is largely oriented towards users, not contributors. if you feel like you've gained some valuable insights through this process that might be helpful for other new contributors, please please do share, and we'll see if we can turn those into docs, too 😄 |
…her importer-level utility functions
Hmm, the appveyor build failed because of an unrelated change. Is that expected? |
} | ||
} | ||
|
||
// If there's *still* no constraint, set the constraint to the revision |
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.
Is this the proper behavior? Should there just not be a constraint if there's no branch specified and no tag that points to the revision?
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.
In general, dep
tries to prevent setting a constraint to a specific revision, that's what the lock is for. The manifest tries to only hold hints on how to update a package, like "I am following the v2 branch" or "Anything less than 2.0.0 please".
Instead of not adding a constraint, what we should do in this case (i.e. they haven't picked a branch and are using a revision that isn't tagged) is to set constraint = gps.Any()
.
The result will be an entry in the manifest without any restriction on it:
[[constraint]]
name = "github.com/carolyn/lovesponies"
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.
We are chugging along! 🚂
} | ||
} | ||
|
||
// If there's *still* no constraint, set the constraint to the revision |
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.
In general, dep
tries to prevent setting a constraint to a specific revision, that's what the lock is for. The manifest tries to only hold hints on how to update a package, like "I am following the v2 branch" or "Anything less than 2.0.0 please".
Instead of not adding a constraint, what we should do in this case (i.e. they haven't picked a branch and are using a revision that isn't tagged) is to set constraint = gps.Any()
.
The result will be an entry in the manifest without any restriction on it:
[[constraint]]
name = "github.com/carolyn/lovesponies"
So, the order of operations to convert a single dependency in a gb manifest is: | ||
- Find a specific version for the revision (and branch, if set) | ||
- If there's a branch available, use that as the constraint | ||
- If there's no branch, but we found a version from step 1, use the version as the constraint |
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.
The inline doc is very helpful! 👍
package main | ||
|
||
import ( | ||
cdt "github.com/carolynvs/deptest" |
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.
You don't have to change what you have here. I just wanted to share another pattern for making tests for dep:
package main
import (
_ "github.com/carolynvs/deptest"
_ "github.com/sdboyer/deptest"
)
func main() {}
} | ||
} | ||
|
||
func TestGbConfig_Convert_BadInput(t *testing.T) { |
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.
Would you please split this into two tests? Or single test with subtests whichever you are more comfortable with. One for the empty package name and another for the empty revision.
[[constraint]] | ||
branch = "master" | ||
name = "github.com/carolynvs/deptest" | ||
source = "https://github.com/carolynvs/deptest" |
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.
These source
fields shouldn't be present, because they aren't forks or non-standard repo locations.
It looks like gb always has pkg.Repository
set... We need to come up some way to tell when we should set source
. 🤔 @sdboyer I assume that gps already has logic that does that but I'm not sure where or it it's exposed.
@avidal Thank for for the head start! @michael-go discovered when he added support for gvt that it also works for gb-vendor. We were able to use some of your logic here in this PR and got support for both merged in #1149. |
What does this do / why do we need it?
This adds a project importer for gb, one more step towards converting all existing dependency managers.
What should your reviewer look out for in this PR?
This was based on a combination of the PR that added the glide importer plus the code in
glide
that added thegb
importer: https://github.com/Masterminds/glide/blob/gps-integration/gb/gb.gogb
(well, more particularly, thegb-vendor
plugin) doesn't save the tag if you fetch by tag, instead it fills in thebranch
key for the dependency with "HEAD", same if you fetch by a specific revision. This PR tries to infer a constraint based on just the revision, but I'm not sure if that's the appropriate behavior or not.references #186