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

Is there a way to install the tool using go get? #66

Closed
zmitry opened this issue Apr 16, 2020 · 17 comments
Closed

Is there a way to install the tool using go get? #66

zmitry opened this issue Apr 16, 2020 · 17 comments

Comments

@zmitry
Copy link

zmitry commented Apr 16, 2020

It would be good to install it using simple go get instead of installing it as npm package.
With this service,(https://gobinaries.com/) you can get binary without golang at all

@tooolbox
Copy link
Contributor

tooolbox commented Apr 16, 2020

Adding a go.mod file is a step in the right direction, but unfortunately go get is not yet supported due to the project's structure.

$ go get github.com/evanw/esbuild
can't load package: package github.com/evanw/esbuild: no Go files in /Users/tooolbox/go/src/github.com/evanw/esbuild

That makes sense because all of the source files are contained in src. Go projects sometimes have a a cmd folder that contains the actual main package that you go get so let's try that:

$ go get github.com/evanw/esbuild/src/esbuild/main
unrecognized import path "esbuild/ast": import path does not begin with hostname
unrecognized import path "esbuild/bundler": import path does not begin with hostname
unrecognized import path "esbuild/fs": import path does not begin with hostname
unrecognized import path "esbuild/lexer": import path does not begin with hostname
unrecognized import path "esbuild/logging": import path does not begin with hostname
unrecognized import path "esbuild/parser": import path does not begin with hostname
unrecognized import path "esbuild/resolver": import path does not begin with hostname

(Just checking...)

$ go get github.com/evanw/esbuild/src/esbuild                                                                                                                                                                
can't load package: package github.com/evanw/esbuild/src/esbuild: no Go files in /Users/tooolbox/go/src/github.com/evanw/esbuild/src/esbuild

Unfortunately, Go Modules has what you might call a lack of support for import paths that do not begin with a domain (the Go Team wants to reserve such domain-less imports for the standard library). The first segment of the import path has to have a . in it or else most operations fail. The sole exception seems to be go build.

Thus, while esbuild has started to use Go Modules 🎉 the best way to enable go get and similar goodies is to change to a github.com/evanw/esbuild/... import path.

Note that because replace directives in go.mod files are not supported for go get and similar operations, this is not a matter of dropping in a go.mod or two and everything Just Works™ as before. The actual import paths/project structure would need to be changed.

There are a couple of examples available of how to do this. Note that if the author is concerned about folks using the code as a library, it can be placed in a directory called internal and no other Go code can import it.


Appendix:

$ GO111MODULE=on go get github.com/evanw/esbuild/src/esbuild/main                                                                                                                                            
go: downloading github.com/evanw/esbuild v0.0.0-20200416222118-5edc934e7a09
go: downloading github.com/evanw/esbuild/src/esbuild v0.0.0-20200416222118-5edc934e7a09
go: found github.com/evanw/esbuild/src/esbuild/main in github.com/evanw/esbuild/src/esbuild v0.0.0-20200416222118-5edc934e7a09
go get: github.com/evanw/esbuild/src/esbuild@v0.0.0-20200416222118-5edc934e7a09: parsing go.mod:
	module declares its path as: esbuild
	        but was required as: github.com/evanw/esbuild/src/esbuild
$ GO111MODULE=on go get github.com/evanw/esbuild/src/esbuild
go: github.com/evanw/esbuild/src/esbuild upgrade => v0.0.0-20200416222118-5edc934e7a09
go get: github.com/evanw/esbuild/src/esbuild@v0.0.0-20200416222118-5edc934e7a09: parsing go.mod:
	module declares its path as: esbuild
	        but was required as: github.com/evanw/esbuild/src/esbuild
$ GO111MODULE=on go get github.com/evanw/esbuild                                                                                                                                                              
go: github.com/evanw/esbuild upgrade => v0.0.0-20200416222118-5edc934e7a09
# Doesn't actually build a binary

@deanishe
Copy link

Having this available as a Go tool would be a real boon. Lack of speed isn't the only issue with JavaScript build systems. It would be great to be able to reduce JS dependencies to only those required by the actual project. Currently, those account for about 1% of the stuff in most of my node_modules directories.

@prantlf
Copy link

prantlf commented May 6, 2020

I wrote a web browser application using Go to run a HTTP server and supply a REST API. It would be great being able to use Go for bundling the static assets too. I would not need Node.js as a build tool to at all. Just Go :-)

@evanw, how about moving go.mod and go.sub to the root of the Github repository, so that it would be recognized as a Go module? Renaming src to cmd might not be necessary:

$ go get -u github.com/evanw/esbuild/tree/master/src/esbuild/...
go get github.com/evanw/esbuild/tree/master/src/esbuild/...:
  module github.com/evanw/esbuild@upgrade found (v0.0.0-20200506071632-d71e12639799),
  but does not contain packages matching github.com/evanw/esbuild/tree/master/src/esbuild/...

$ go get -u github.com/evanw/esbuild/src/esbuild/...
go: downloading github.com/evanw/esbuild/src/esbuild v0.0.0-20200506071632-d71e12639799
go: found github.com/evanw/esbuild/src/esbuild/...
      in github.com/evanw/esbuild/src/esbuild v0.0.0-20200506071632-d71e12639799
go get: github.com/evanw/esbuild/src/esbuild@v0.0.0-20200506071632-d71e12639799:
  parsing go.mod:
    module declares its path as: esbuild
    but was required as: github.com/evanw/esbuild/src/esbuild

$ go get -u github.com/evanw/esbuild/...
go get github.com/evanw/esbuild/...:
  module github.com/evanw/esbuild@upgrade found (v0.0.0-20200506071632-d71e12639799),
  but does not contain packages matching github.com/evanw/esbuild/...

@prantlf
Copy link

prantlf commented May 6, 2020

Well, I was too naive to say, that just moving go.mod and go.sub would do. I inspected the project sources and made some changes to get a prototype running. They were pure restructuring. No code changes except for renaming the internal imports were needed.

  • Move go.mod and go.sub to the project root.
  • Name the module github.com/evanw/esbuild instead of esbuild.
  • Move the main package from /src/esbuild/main to /cmd/esbuild.
  • Move all other packages to /internal. Some of them can be made public later.
  • Import packages by github.com/evanw/esbuild/internal/... instead of esbuild/....
  • Adapt Makefile to work with the new structure.

In the end I was able to successfully build and test the package. When I tested it externally, I had to rename the package in my fork, but if you imagine evanw instead of prantlf there, you will get the idea :-)

go get -u github.com/prantlf/esbuild/...@308fdf459d65

I kept the change in a separate branch. Would you be interested in a PR? Of course, that that branch will work only with your change d71e126, which I forked. I am not sure if rebase on a newer state of your repository will work with so many moved files. If you were interested, I would make the changes again to your latest sources, whenever you were ready.

evanw added a commit that referenced this issue May 7, 2020
evanw added a commit that referenced this issue May 7, 2020
evanw added a commit that referenced this issue May 7, 2020
@evanw
Copy link
Owner

evanw commented May 7, 2020

Ok I attempted to do this. Can someone confirm if this works? I'm not familiar with Go modules, so I'm not sure what to test.

@deanishe
Copy link

deanishe commented May 7, 2020

Can someone confirm if this works?

It does. You may need to run GO111MODULE=on go get -u github.com/prantlf/esbuild/...@308fdf459d65 to install it if you're getting the error go: cannot use path@version syntax in GOPATH mode

@evanw
Copy link
Owner

evanw commented May 7, 2020

Thanks for confirming! I'll consider this issue fixed then.

As an additional data point, I was also able to successfully download an esbuild executable from https://gobinaries.com. It appeared to be around the correct size. I didn't run it though.

@evanw evanw closed this as completed May 7, 2020
@prantlf
Copy link

prantlf commented May 7, 2020

Thank you, @evanw, it works perfectly! When running in a Go module directory using Go 1.14, the binary esbuild gets installed and put to PATH (actually, GOBIN):

$ go get -u github.com/evanw/esbuild/...
go: downloading github.com/evanw/esbuild v0.0.0-20200507102806-766e48876293
go: found github.com/evanw/esbuild/...
      in github.com/evanw/esbuild v0.0.0-20200507102806-766e48876293
go: golang.org/x/sys upgrade => v0.0.0-20200501145240-bc7a7d42d5c3
$ which esbuild
/Users/prantlf/go/bin/esbuild

Beware of git tags, though. You have not tagged any commit in your repository yet. That is why if I run go get -u ... everyday, I will be able to enjoy your latest changes everyday (if I wanted) :-) As soon as you decide to tag your commits to match your releases, Go will use the latest of them according to the semantic versioning concept. It means that if you do not tag the commit which you want to release, Go users will not get an upgrade offered.

You can work without tags on the road to MVP. If somebody wants to stay with a particular change, they can refer to it by its commit hash, when they install the tool. For example:

go get -u github.com/evanw/esbuild/...@766e48876293

As soon as you decide to start tagging your commits, people who install esbuild by go get will get the latest release, not the latest master, just like NPM users do today. Once you decide, I recommend you the usual semantic versioning format used by both Go and NPM packages. For example, your current version that you released to NPM would be tagged byv0.2.8.

Thanks again for the quick implementation!

@prantlf
Copy link

prantlf commented May 7, 2020

About downloading binaries - you can have a look at GoReleaser too. If you write a goreleaser.yml, tag a commit for a new release and run .goreleaser --rm-dist. It will build binaries for all platforms, upload them to GitHub and generate a changelog entry with hyperlinks. This is more for the future, when esbuild gets more stable.

By the way, NPM releases can be automated in a similar way with semantic-release, if you were interested. Basically, you prefix your commits with chore: (not versioning change), fix: (patch version), feat: (minor version) or include BREAKING CHANGE: in the commit description (major version) and run npx semantic-release, when you are ready to push all changes. It will bump the version properly and publish your module at npmjs.org.

Both go-release and semantic-release can be run in CI pipelines like Travis, so that you do not need to do the "paperwork" yourself.

@tooolbox
Copy link
Contributor

tooolbox commented May 7, 2020

Stupendous; can confirm this works.

@evanw It would be nice, when you do a version bump on NPM, to add a git tag for the same version.

@evanw
Copy link
Owner

evanw commented May 7, 2020

I'll add tags for future releases. I want esbuild's command-line tool to be usable for real things, so I don't think downloading master is an appropriate default.

Unfortunately semantic versioning doesn't really apply before 1.0.0. The semver docs say this:

Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.

However, during the MVP phase I'd like to be a bit more rigorous about this. I'm planning to use patch releases for backwards-compatible changes and bug fixes, and minor releases for either major features or backwards-incompatible changes. So if you stick to just patch releases than the command-line interface should remain pretty stable.

evanw added a commit that referenced this issue May 7, 2020
@tooolbox
Copy link
Contributor

tooolbox commented May 7, 2020

I'll add tags for future releases.

Awesome, thanks.

Unfortunately semantic versioning doesn't really apply before 1.0.0.

That's fine, users of Go Modules will understand that things may break before 1.0.

From https://blog.golang.org/v2-go-modules:

For projects that are still experimental — at major version v0 — occasional breaking changes are expected by users. For projects which are declared stable — at major version v1 or higher — breaking changes must be done in a new major version.

@zamicol
Copy link

zamicol commented Sep 20, 2022

As always evanw, thank you for your hard work.

Wanted to chime in, I was hoping this would work. It would be nice, but not a big deal.

go install github.com/evanw/esbuild@0.15.8

Instead, I needed something like this:

mkdir -p $GOPATH/src/github/evanw
cd $GOPATH/src/github/evanw
git clone --depth 1 --branch v0.15.8 https://github.com/evanw/esbuild.git
cd esbuild
go build ./cmd/esbuild
sudo cp esbuild $GOPATH/bin

(I have GOPATH set while also using mod. I like the organization of the "old ways", but GOPATH isn't required here.)

@tooolbox
Copy link
Contributor

tooolbox commented Sep 21, 2022

I think you want go install github.com/evanw/esbuild/cmd/esbuild@v0.15.8 using Go 1.16 or newer.

@zamicol
Copy link

zamicol commented Sep 21, 2022

@tooolbox Yes, that would be great.

@tooolbox
Copy link
Contributor

I believe the command I gave should work. Not at my dev machine to try right now, but please give it a shot, and report the exact error if any.

@zamicol
Copy link

zamicol commented Sep 21, 2022

With the edit, yes that works. Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants