Closed jefferai closed 6 years ago
hi, welcome! this is an interesting one 😄
easy thing first:
(Side question: since its inception Vault has put a v in front of tags; does dep deal with stripping that off before semvering what's there?)
yep. this actually the source of some consternation for me, because we consider tags with and without the leading v
to be equivalent. i can't actually recall what happens when both exist, but i believe one clobbers the other. more tests & checks needed. anyway:
they both have a dependency on each other. In reality only certain packages in the Vault repo are needed,
we do support project-level cycles, at least in part. (technically we don't disallow package-level cycles, either, but only because it's yet to actually be a problem for anyone, and i've yet to find an efficient incremental graph cycle detection algorithm). we added support for it right around when we opened dep up - #116. but, back then, nobody was using dep, so there was no possibility of there being constraints declared back onto the root project. i didn't think about it in the initial implementation, so i just didn't cover that case - as evidenced by some of those failure messages simply stopping mid-sentence. that happens because we treat the root project specially in several ways within the solver, the relevant one here being that the root project is treated as versionless.
i don't think the mechanics of a fix here are going to be very hard, but it's also not immediately clear to me what we should do. the only solution that's readily apparent to me is that, when a project-level cycle passes back through the root project, we simply drop any explicit constraints there.
the only immediate drawback i can think of - and this is just OTTOMH, it might not be a thing - is that it might be easy to create situations that are unresolvable, or at least where certain versions become unreachable, for either vault
or vault-plugin-auth-gcp
's dependers because constraints declared in one or the other project are only satisfiable when the other project's constraints are knocked out by my proposed rule.
Possibly this can be addressed using an override? But didn't quite see what I'd specify.
maybe, although i think the only thing that really work in the override is an "any", which i believe we don't actually allow the user to explicitly specify.
Thanks for the detailed write up!
The only thing I can think of offhand, and I realize this is likely yucky but I have 0.01% of your experience in this area, is to be able to declare an explicit binding between repos such that the constraint is that the revisions match. E.g. the branch must be master for both, or they must be using the same tag, or something. Then you can assume that they are in sync and add them as is rather than solving.
That probably doesn't make much sense, and it also doesn't solve the init problem, but thought I'd throw it out there.
an explicit binding between repos such that the constraint is that the revisions match. E.g. the branch must be master for both, or they must be using the same tag, or something. Then you can assume that they are in sync and add them as is rather than solving.
iiiiiinteresting!
it likely would be yucky, but i haven't seriously explored a line of thought like this before. it has a pretty clear antecedent in graph theory - vertex contraction - which at least means that i can consider its effects on the system in a more formal way. my gut says that we'd need to find more reasons for doing something like this than just this one, but because it rests on this mathematical foundation, we could likely find some. (though still, maybe too yucky)
doesn't solve the init problem
yeah, this is a trickier thing. we're having more and more init smoothness problems recently, but this is one that goes deep. i think we may not have much choice but to do the "ignore root constraints" thing i laid out in order to make init - and subsequent ensures - workable at all.
thought I'd throw it out there.
🎉 🎉 please, don't hesitate to do this!
I believe other HashiCorp products might also have this issue. Terraform for instance split its providers out into separate packages to make it easier for contributors to work on just a single chunk of code, but IIRC it means they need to import helper libraries and structs/interfaces from the main repo and it has to import many of these providers to build into the binary.
I realize this is likely to only affect projects using a plugin based model. OTOH Go now added first party support for plugins which probably makes this scenario more likely going forward.
I believe other HashiCorp products might also have this issue
honestly, i'd like it to be more common for other orgs to at least feel comfortable with doing things like this. it's also something that might benefit k8s - we're in the midst of trying to figure out how to support their staging/
dir, which isn't a plugin-style use case, but is still an issue trying to have projects where the development is closely coupled with a given repository "move with" that repository, while still having a canonical identity external to it.
(in fact, /cc @sttts @kris-nova - this may end up relating to k8s things)
OTOH Go now added first party support for plugins which probably makes this scenario more likely going forward.
i opened #347 a while back, but we backburnered it b/c there are just so many problems with the language's plugin system that the whole area is rather anemic right now. i actually wonder if causality may end up flowing in the other direction - with improved package management, plugins become more feasible to actually use in production, which in turn structures and drives improvements in the language support for them. ¯\_(ツ)_/¯
Don't know where the issue is at, but a colleague of mine wrote a quick fix that I've added to a fork of mine, thought I'd throw it in there in case that may help finding a more durable solution:
https://github.com/asticode/dep/commit/942f050b345a2ae531651f42d28266a5889a5301
@asticode yeah, that's the naive fix (well done finding that deep in the solver, lol 😜). if we denote the root project with an (r)
, it solves this problem:
A(r) <-> B
The thing i'm trying to find time to grapple with in finding that more durable solution is what that means when A is published, and this situation then occurs:
C(r) -> A <-> B
i don't think there's really much to be done here, per se, but i want to get my head around the possible effects before introducing this kind of change into the ecosystem. this kind of variability, while convenient in the small, could potentially produce very confusing situations in the large.
Jumping in, I've also been facing a similar issue with #1842. Perhaps a starting point would be to add an experimental flag when running dep
to skip circular dependencies?
It's currently breaking our CI as dep
fails to resolve dependencies. The current dirty fix is to use -vendor-only
when running dep ensure
in CI and setting the versions manually, but it seems counter-intuitive.
@manuel-huez it'll likely require too much reworking of things to make this work cleanly in dep as-is, so i'm going to defer this to dep's successor tool. More info on that soon™ 😄
I'd like to a see an experimental flag which implements https://github.com/asticode/dep/commit/942f050b345a2ae531651f42d28266a5889a5301 so at least dep
can handle more cases than it can today, rather than waiting for months/years for another tool to do it. Gating it behind appropriately scary-sounding flag names seems reasonable.
I've recently hit this issue, and it's frustrating knowing that there is a workaround available.
What version of
dep
are you using (dep version
)?v0.3.0-248-gd3e738d
What
dep
command did you run?dep init -v
(see output below)What did you expect to see?
Dep builds Gopkg.* files.
What did you see instead?
Note: I did not cut off the output -- it ends with
selected version of <blank>
.This may be related to #1125.
Right now I have one package using dep and another using govendor. The project using dep is https://github.com/hashicorp/vault-plugin-auth-gcp which currently is depending on
master
of https://github.com/hashicorp/vault(Side question: since its inception Vault has put a
v
in front of tags; does dep deal with stripping that off before semvering what's there?)Right now Vault uses govendor and has these stanzas -- note how the packages are separate:
I wanted to try switching Vault over to dep. But since the first package is a plugin of Vault, and since Vault builds the plugin internally into itself when possible, they both have a dependency on each other. In reality only certain packages in the Vault repo are needed, but splitting them out of the Vault repo isn't really feasible (again, the plugin is also built-in internally when possible).
No matter what revision/tag/whatever I try specifying in the plugin's Gopkg file, the result is the same other than in the output saying "...a dependency on github.com/hashicorp/vault with constraint ^0.8.2...". The last part of it "...currently selected version of" always ends blank.
Possibly this can be addressed using an override? But didn't quite see what I'd specify. Maybe I need to hand-create a Gopkg.toml? But if I do that, will future runs of
dep ensure
still have a problem, and/or will they add any direct dependencies I missed, and what should be inside that file?