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

Wiki: document how to fork a package and use that fork in your project #39889

Closed
matthewmueller opened this issue Jun 27, 2020 · 4 comments
Closed

Comments

@matthewmueller
Copy link

matthewmueller commented Jun 27, 2020

This falls on the edge of proposal and question. I've been working with Go for a couple years now, but I'm still unsure what the recommended workflow is for forking a Go package and using that package in your code. I think documenting this workflow would enable so much more code sharing across the Go community.

To illustrate the problem, I've documented my experience report below as an "experienced gopher" trying to fork https://github.com/evanw/esbuild to expose the parser from internal/:

I first tried https://godoc.org/golang.org/x/tools/cmd/gomvpkg to move a package and update the imports. This doesn't work with go modules yet.

Next, I googled around and learned about go mod edit. I tried go mod edit -module $module. This does rename my module, but not everything else.

I googled some more but kept finding old articles that either don't use go modules or use other package management tools like glide.

Then I thought that maybe go mod handles this automatically nowadays. So I just forked https://github.com/evanw/esbuild to https://github.com/matthewmueller/esbuild, then tried go get -u github.com/matthewmueller/esbuild. This returns the following error:

go: github.com/matthewmueller/esbuild upgrade => v0.5.13
go get: github.com/matthewmueller/esbuild@v0.5.13: parsing go.mod:
	module declares its path as: github.com/evanw/esbuild
	        but was required as: github.com/matthewmueller/esbuild

This is where I'm at right now. I guess I'll rename all of github.com/evanw/esbuild to github.com/matthewmueller/esbuild using find and replace. Then move internal/ to pkg/. Since esbuild is a fast-moving project, I'll likely need to update this frequently and deal with merge conflicts each time.

I'd love to hear what others do. I'm happy to write something in the wiki once we figure out how to do this. If it's not currently possible, I'd be happy to help make this workflow better. Please let me know!

@matthewmueller
Copy link
Author

matthewmueller commented Jun 27, 2020

Update: It turns out go mod does handle this automatically nowadays! While I'm still not sure why go get -u github.com/matthewmueller/esbuild doesn't work, go get -u github.com/matthewmueller/esbuild@master does.

@melbahja
Copy link

I think if you changed module in go.mod in your fork from github.com/evanw/esbuild to github.com/matthewmueller/esbuild, and add replace github.com/evanw/esbuild => ./, it may works

@matthewmueller
Copy link
Author

matthewmueller commented Jun 29, 2020

Thanks for the response @melbahja. I've tried that and wasn't able to get it working. Same errors:

go: found github.com/matthewmueller/esbuild/... in github.com/matthewmueller/esbuild v0.5.13
go get: github.com/matthewmueller/esbuild@v0.5.13: parsing go.mod:
	module declares its path as: github.com/evanw/esbuild
	        but was required as: github.com/matthewmueller/esbuild

I'm also no longer able to use @master above. I'm not sure what changed.

go: github.com/matthewmueller/esbuild master => v0.5.14-0.20200629194630-11ba82c5474b
go get: github.com/matthewmueller/esbuild@v0.5.14-0.20200629194630-11ba82c5474b: parsing go.mod:
	module declares its path as: github.com/evanw/esbuild
	        but was required as: github.com/matthewmueller/esbuild

What does required mean in this case? Required by go get?

@matthewmueller
Copy link
Author

matthewmueller commented Jun 29, 2020

I found it! And it is pretty much documented already! It works without messing with the fork's go.mod or imports, which is really neat.

https://github.com/golang/go/wiki/Modules#when-should-i-use-the-replace-directive

module github.com/matthewmueller/svelte

go 1.14

require (
	github.com/evanw/esbuild v0.5.14
	github.com/matthewmueller/diff v0.0.0-20191220174011-88a65b538395
	github.com/tj/assert v0.0.3
)

replace github.com/evanw/esbuild => github.com/matthewmueller/esbuild master

Then you just run go mod tidy.

You need the master otherwise go mod tidy expects a relative path. Running go mod tidy will also replace master with a version + hash:

module github.com/matthewmueller/svelte

go 1.14

require (
	github.com/evanw/esbuild v0.5.14
	github.com/matthewmueller/diff v0.0.0-20191220174011-88a65b538395
	github.com/tj/assert v0.0.3
)

replace github.com/evanw/esbuild => github.com/matthewmueller/esbuild v0.5.14-0.20200629194630-11ba82c5474b

Also, I guess the wiki is public, hah. I just added the following note:

You can also reference branches, for example:

replace example.com/some/dependency => example.com/some/dependency-fork master

Closing. Working as expected and documented.

@golang golang locked and limited conversation to collaborators Jul 2, 2021
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

3 participants