goatlang / goat

Extended flavor of the Go programming language, aiming for increased value safety and maintainability
MIT License
63 stars 1 forks source link

Please add a shebang/execution mode #7

Open guilt opened 1 year ago

guilt commented 1 year ago

I would be really interested in trying goat if there could be a shebang mode;

The idea is to write better statically checked scripts than bash/python for a variety of ops tasks.

avivcarmis commented 1 year ago

@guilt would you be able to explain a bit or provide an example from other languages? How do you imagine it? How does it work? What does it solve? It sounds very interesting and personally, I'm not sure I fully understand

guilt commented 1 year ago

An example of how this would look like, is given in here

Essentially, this means having # as a comment line in golang, and that too, only required for the very first line.

#!/usr/bin/env go run  

is how the script would be invoked.

Scripts are written for routine system maintenance, infrastructure as code and plain old utilities. Many of them could be written as go files and invoked as scripts (as opposed to building and shipping binaries)... A lot of important infrastructure components are written in Go (Docker, k8s, Terraform etc.) and it would make sense to be able to invoke libraries as opposed to commands.

See Pulumi examples for this approach.

avivcarmis commented 1 year ago

So this would let you execute the go file by running ./main.go instead of go run main.go? So what's the advantages here? Aside for shorter shell commands? Is there any further ability?

guilt commented 1 year ago

It makes scripting in go an easy construct, very much like python and perl. The only difference between those languages is that: go has better type safety. When used for infra tooling, this gives folks the ability to start writing/testing their better written utilities in go, and have direct access to the internals of many bespoke commands already written in go.

avivcarmis commented 1 year ago

@guilt I'm not that strong in scripting procedures per say, I'm sure what are the implications of designing goat as a scripting language and I'd like to get more opinions here. Would there be any follow up requirements?

Adding # comments is quite a big fragmentation. Adding only first line support for shebangs seems more reasonable but I'm not sure what the implications are. Would you like to c check into it a bit more?

Also, I didn't really understand if there's anything more than shortening go run main.go to ./main.go. you mainly talked about the advantages of go over scripting languages which i fully agree with

guilt commented 1 year ago

Adding support for just the first line should be enough. Imagine this as equivalent to shipping scripts as code and making go as the base for writing systemwide scripts as necessary. I believe this would help with that.

When it comes to prototyping scripts or utilities, the shebang mode can certainly help with that. Since the go toolchain is fairly self-contained it may be a great step towards increasing go adoption for system wide scripting as well.

avivcarmis commented 1 year ago

I'm still not sure about what I asked... shortening go run main.go into ./main.go is fairly nice, does it have any practical implications other than being a bit shorter to write? If i understand correctly, it's some kind of a standard that you believe should push towards more adoption in system scripting?

I agree that adding # support in the first line alone is relatively simple. however I want to make sure we fully understand what we're going into if we do

guilt commented 1 year ago

A shebang is a well known Unix standard that allows folks to put an invocation in the very first line, and what happens is that it allows the file to exec, and the execution takes care of reading the file, and if a shebang is found, uses the shebang line to be executed, and adds the file name as an argument to the end of it, and calls exec.

So, if a #!/bin/sh was found at the beginning of a file called a.sh and you ran ./a.sh, it internally gets translated into an exec of /bin/sh "a.sh"

go already allows people to run a .go file as a script but where it fell short was being able to invoke via a shebang. The shebang mechanism is part of standard Unix, and for that to work with an interpreter, golang simply has to be able to ignore the first line as a comment, that is all.

If implemented correcrly, the shebang in the first line of an executable file would look like:

#!/usr/bin/env go run

followed by package main and the rest of the code.

guilt commented 1 year ago

Right now, there is a third party utility that has been written to do this, but the proposal asks for inclusion in the standard go interpreter for main files.

https://wiki.ubuntu.com/gorun

marcelloh commented 1 year ago

I like the idea, but it's also a bit scary, because "non" developers might up destroying their system and Go gets the blame.

I assume that such a "script" has a main function. How would this behave if you have multiple scripts in the same folder?

guilt commented 1 year ago

Each go file that is runnable would get a shebang, and should be marked executable (x bits)

avivcarmis commented 1 year ago

I think @marcelloh was referring to the fact that each go file would need to contain a main function, but it won't compile since main will have already been declared in this package

marcelloh commented 1 year ago

Well I think this could work if the executable is done in a tmp dir (like gorun does)