Dependency hierarchy in go

179 views
Skip to first unread message

kuznetso...@gmail.com

unread,
Feb 7, 2020, 4:55:26 AM2/7/20
to golang-nuts
Hello!

Project A depends on B and B depends on C. A -> B -> C. When I create fork of C = C1 with new features I will add go.mod replace command like that "replace C => C1". But when I import B in project A got missing C1 replace command in go.mod is it intended feature or bug? As result my project wont compiling until I understand what is going in and manually add "replace C => C1" in project A.

kuznetso...@gmail.com

unread,
Feb 7, 2020, 2:01:19 PM2/7/20
to golang-nuts
I'm I bad at explaining? Simple form:

A (go.mod = require B) -> B (go.mod = require C; replace C=>C1) -> C1

'A' failed to compile because it does not see C=>C1 replace in child project. Does GO require to copy all replace commands from all child projects in main go.mod manually or is it a bug?

Jason Phillips

unread,
Feb 7, 2020, 2:35:37 PM2/7/20
to golang-nuts
Replace only works for the top-level go.mod. From the proposal doc (link):
Minimal version selection gives the top-level module in the build additional control, allowing it to exclude specific module versions or replace others with different code, but those exclusions and replacements only apply when found in the top-level module, not when the module is a dependency in a larger build. 
A module author is therefore in complete control of that module‘s build when it is the main program being built, but not in complete control of other users’ builds that depend on the module. I believe this distinction will make this proposal scale to much larger, more distributed code bases than the Bundler/Cargo/Dep approach.

And from the GoWiki module page (link):
replace allows the top-level module control over the exact version used for a dependency

kuznetso...@gmail.com

unread,
Feb 7, 2020, 2:49:46 PM2/7/20
to golang-nuts


On Friday, February 7, 2020 at 10:35:37 PM UTC+3, Jason Phillips wrote:
Replace only works for the top-level go.mod. From the proposal doc (link):
Minimal version selection gives the top-level module in the build additional control, allowing it to exclude specific module versions or replace others with different code, but those exclusions and replacements only apply when found in the top-level module, not when the module is a dependency in a larger build. 
A module author is therefore in complete control of that module‘s build when it is the main program being built, but not in complete control of other users’ builds that depend on the module. I believe this distinction will make this proposal scale to much larger, more distributed code bases than the Bundler/Cargo/Dep approach.


Thank you for explaining. Looks like bad by design, since I can not create patched libraries. Like mine: https://gitlab.com/axet/libtorrent

roger peppe

unread,
Feb 10, 2020, 5:42:34 AM2/10/20
to kuznetso...@gmail.com, golang-nuts
If you want to provide a library that's not a hard fork, just a patched version, you can always use the original module name. Any users would need to add a replace directive to use it.

There's nothing stopping you creating a forked version of that library - just change import statements appropriately.

There's a very good reason for ignoring replace statements in dependencies - it keeps Go module dependency resolution from being NP-complete and is a key enabler for Go's high fidelity builds. See this link for more background: https://research.swtch.com/vgo-mvs.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/127983cb-cbea-437d-9d54-2d1c2d729523%40googlegroups.com.

kuznetso...@gmail.com

unread,
Feb 10, 2020, 6:10:08 AM2/10/20
to golang-nuts


On Monday, February 10, 2020 at 1:42:34 PM UTC+3, rog wrote:
On Fri, 7 Feb 2020 at 19:47, <kuznets...@gmail.com> wrote:


On Friday, February 7, 2020 at 10:35:37 PM UTC+3, Jason Phillips wrote:
Replace only works for the top-level go.mod. From the proposal doc (link):
Minimal version selection gives the top-level module in the build additional control, allowing it to exclude specific module versions or replace others with different code, but those exclusions and replacements only apply when found in the top-level module, not when the module is a dependency in a larger build. 
A module author is therefore in complete control of that module‘s build when it is the main program being built, but not in complete control of other users’ builds that depend on the module. I believe this distinction will make this proposal scale to much larger, more distributed code bases than the Bundler/Cargo/Dep approach.


Thank you for explaining. Looks like bad by design, since I can not create patched libraries. Like mine: https://gitlab.com/axet/libtorrent

If you want to provide a library that's not a hard fork, just a patched version, you can always use the original module name. Any users would need to add a replace directive to use it.

There's nothing stopping you creating a forked version of that library - just change import statements appropriately.

There's a very good reason for ignoring replace statements in dependencies - it keeps Go module dependency resolution from being NP-complete and is a key enabler for Go's high fidelity builds. See this link for more background: https://research.swtch.com/vgo-mvs.

I see it opposite to "fidelity builds". This library 100% failed if replace directive is not used. Go at least can automatically add 'replace' directive in main go.mod.
Reply all
Reply to author
Forward
0 new messages