Skip to content

proposal: Replace in-house implementation of gopherjs build tool with augmented forked cmd/go build tool. #388

Closed
@dmitshur

Description

@dmitshur

The GopherJS project has developed the gopherjs tool. Its CLI mimics a lot of the commands that go tool (import path cmd/go, in GOROOT) offers, in addition to one new command serve (see #268). However, it's missing some features of the real cmd/go (see issues labeled cmd/go for some examples).

Instead of continuing to develop and maintain the gopherjs tool ourselves, I propose we replace the custom implementation of gopherjs with a modified fork of the real cmd/go that has 2 changes cherry-picked on top. All existing functionality would be preserved, gaining missing features, fixing bugs, and reducing overall maintenance cost. The only functionality that the current gopherjs tool offers but cmd/go doesn't is the serve command, and we will preserve it in some way (details to be determined).

Plan

At a high level, my proposed plan is:

  1. Wait for Go 1.6 release, or combine this plan with adding suppport for Go 1.6.
  2. Create a fork of cmd/go.
  3. Create a change that can be cherry-picked (or rebased) on top of latest upstream cmd/go that makes the command go-gettable.
    • This is a small change.
  4. Create a change that can be cherry-picked (or rebased) on top that adds support for -compiler=gopherjs value.
    • This is a larger change, but it can be done cleanly and will result in significant simplification in the work that GopherJS needs to do, stripping away a lot of its responsibility as a build tool, leaving only the compilation and linking to be done.
  5. Continue to make the augmented cmd/go available and maintain it by simply taking the latest upstream code and rebasing the 2 cherry-picked changes on top.
    • When the plan is complete and the changes are reviewed and made clean, and everything proves to be stable, we can attempt to make a CL to merge the -compiler=gopherjs support addition upstream into core Go repository, and learn if there are any blockers from making that possible. If not accepted, we can continue to maintain the forked tool ourselves with low maintenance overhead.

The end result will be a fully capable cmd/go-like command that will support compiling with GOARCH=js set. It will be able to go run and go test by setting -exec=node. It will resolve all these issues and simplify original code that GopherJS project has to maintain.

Research and viability

I have explored this idea recently by attempting to do this during a 48-hour Gopher Gala 2016 hackathon. The project, which was mostly me learning about how cmd/go is structured and works, can be seen here:

https://github.com/gophergala2016/cmd-go-js#readme

It partially implements what I have described above, but not completely. Due to time constraints, I did not attempt to make changes to gopherjs binary and simply used it as it exists today. This allowed me to implement go build and go run, but not the other commands.

To have all other features work as expected, the entire toolchain interface needs to be implemented correctly.

You can read the README of the linked project for additional details and observations.

Mockup

Here's a mockup demonstrating how the new build tool for GopherJS would look like:

One possible simplification might be that setting -compiler=gopherjs explicitly won't be needed when GOARCH=js is already set. That would allow typed commands to be shorter.

Summary

By implementing this plan, the end result is expected to:

  • Continue to provide all existing functionality, while resolving many bugs and implementing missing functionality of the cmd/go build tool.
  • Remove most of the current "build tool" code, allowing GopherJS to focus on being a pure Go compiler and linker for JavaScript architecture.
  • Reduce the total maintenance cost since it's expected the effort to rebase the 2 clean changes on top of cmd/go will be much smaller than to keep developing and maintaining gopherjs tool ourselves.
  • A real go tool should be more familiar and friendly to new people, since most Go developers are very familiar with the cmd/go tool and its flags.
    • Compiling with GopherJS can be seen just like cross-compiling to another OS/architecture, which is a common and well understood concept.

I've discussed this plan with @neelance and agreed it sounds favorable. What's next is to attempt to execute it and ensure no major blocking issues come up.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Proposalgopherjs-toolRelated to the gopherjs tool or its build system (but not the compiler itself).

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions