45

proposal: Support writing scripts in Go via a shebang · Issue #32242 · golang/go

 4 years ago
source link: https://www.tuicool.com/articles/JRZbyif
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Introduction

I really like Go. I want to use it to write scripts with a shebang the same way I write bash, python and node scripts. The localization of the code with the executable enables a very nice and simple workflow compared to creating a new Go package or module.

  1. I don't have to worry about $GOPATH/bin .
  2. I can place my scripts wherever I want.
  3. I can just use type binaryname to figure out where my source code is.
  4. There is no install step.
  5. This gist summarizes why Go and not another language

Previous discussions

This is not a new idea. It has been argued many, many times in the past on this tracker and on the mailing list.

  1. #28496
  2. #24118
  3. https://groups.google.com/forum/#!topic/golang-nuts/iGHWoUQFHjg/discussion
  4. https://groups.google.com/d/msg/golang-nuts/cF-1uBSJPiY/aX6BBPjvrdUJ
  5. https://gist.github.com/posener/73ffd326d88483df6b1cb66e8ed1e0bd

The main argument against this feature has been the performance implications. As summarized by Rob Pike :

Running compilers and linkers, doing megabytes of I/O, and creating temporary
binary files is not a justifiable expense for running a small program. For large
programs, the amortization is even more in favour of not doing this.

I am firmly against adding a feature to Go that encourages abuse of resources.

Proposal

I think its time to revisit this as the performance argument is not valid anymore with the introduction of the build cache . If the script hasn't changed, it will not be rebuilt on every go run .

Furthermore with the introduction of Go modules, $GOPATH is being phased out and it's become idiomatic for Go code to be anywhere on the system. Given Go has become more flexible with project layout in line with other languages, I argue it's natural the same apply to scripts. Rust, node, python, ruby and almost every other modern programming language supports the shebang.

Moreover, with the amount of discussion on the mailing list and this tracker, it's clear there is strong demand for this feature.

https://github.com/erning/gorun enables shebang support now. But for the reasons outlined above, shebangs should become a first class feature.

The concrete changes I propose:

  1. Extend the Go grammar to include shebangs.
    1. Shebangs would only be accepted as the first line of a Go file.
    2. Shebangs would be completely ignored by all Go tooling and any files with a shebang would act exactly like normal Go code.
  2. Include a gox binary with the Go distribution. It would act exactly as go run but would be the interpreter in the shebang line for scripts. See this gist for why this is necessary.
    1. The only change from go run would be that it proxies the exit code instead of consuming it. See #13440

Under the proposed changes, a script hello-world would look like:

#!/usr/bin/env gox

package main

import "fmt"

func main() {
    fmt.Println("Hello World!")
}

And could be executed with ./hello-world .

Its unfortunate to break the convention that all Go code is in a file with a .go extension but I think it's a fair tradeoff for the convenience.


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK