19

For example there is a -c option in Ruby that checks syntax before running a code:

C:\>ruby --help
Usage: ruby [switches] [--] [programfile] [arguments]
-c              check syntax only

C:\>ruby -c C:\foo\ruby\my_source_code.rb
Syntax OK

Is there a similar functionality in Go?

P.S. An example from Ruby is only because I know it in Ruby. Not because of trolling or something.

TheHippo
  • 61,720
  • 15
  • 75
  • 100
Green
  • 28,742
  • 61
  • 158
  • 247

6 Answers6

31

You can use gofmt to check for syntax errors without actually building the project.

gofmt -e my_file.go > /dev/null

You can later use $? bash variable, return code 0 implies success, 2 means syntax check. /dev/null will eat the code, but the errors go to stderr

The -e option is defined as:

report all errors (not just the first 10 on different lines)


gofmt --help

usage: gofmt [flags] [path ...]
  -comments=true: print comments
  -cpuprofile="": write cpu profile to this file
  -d=false: display diffs instead of rewriting files
  -e=false: report all errors (not just the first 10 on different lines)
  -l=false: list files whose formatting differs from gofmt's
  -r="": rewrite rule (e.g., 'a[b:len(a)] -> a[b:]')
  -s=false: simplify code
  -tabs=true: indent with tabs
  -tabwidth=8: tab width
  -w=false: write result to (source) file instead of stdout
Felipe Valdes
  • 1,998
  • 15
  • 26
  • There is also `go vet` and `golint` which take a even deeper look at your code. – TheHippo Nov 09 '14 at 17:48
  • This doesn't actually report all errors that `go build` might so is not a suitable answer. – Ash Berlin-Taylor May 23 '16 at 14:10
  • 2
    OK this does actually work at a second check, just need to redirect stdout to /dev/null like `gofmt -e file.go >/dev/null` – ekerner Mar 14 '17 at 16:12
  • OK I made Crazy Trains answer into a bin util script, please scroll down to find it. Works like: `gochk handlers/*.go stores/*.go` – ekerner Mar 14 '17 at 17:42
  • I took your advice and turned it into a command line utility, so it runs before I "git add" the incorrect files, I called g, it's here: https://github.com/dataf3l/g/ thank you for your advice. – Felipe Valdes Jul 20 '19 at 13:10
  • On my PC, `gofmt` can't do syntax checking, it can only format the code. WHY? – Yves Mar 24 '20 at 10:07
3

Is there much point only checking the syntax? The Go compiler is so fast you might as well compile everything too.

In this sense, the underlying mental model is quite different from that of Ruby.

Just use go build or go install. http://golang.org/cmd/go/

Rick-777
  • 9,714
  • 5
  • 34
  • 50
  • Most of the time you don't want to upload, commit, deploy or waste time building something with incorrect syntax. Checking the syntax would be done before doing any of above. – Gustav Sep 30 '14 at 11:10
  • Why would you want to upload, commit, deploy or waste time building something that hasn't been compiled yet? This is kind-of the point. The `go` tool does syntax checking and compilation very fast so there's nothing to be gained by having "only" a syntax checker. When compilation has succeeded, then upload, commit, deploy etc to your heart's content. – Rick-777 Sep 30 '14 at 13:05
  • 1
    In some cases you can't compile and test the whole program on your own computer. Think of a CAN-network in a car, not that easy to test on a personal computer. – Gustav Oct 01 '14 at 09:31
2

Ruby is an interpreted language so a command that checks the syntax might make sense (since I assume you could potentially run the program even if there are syntax errors at some point).

Go on the other hand is a compiled language so it cannot be run at all if there are syntax errors. As such, the simplest way to know if there are errors is to build the program with go build.

laurent
  • 88,262
  • 77
  • 290
  • 428
  • 2
    This is factually incorrect. All modern interpreted languages compile to an intermediate representation (bytecode/opcodes) which are then interpreted. These are not some ancient BASIC where each line is parsed every time before it is executed. The `-c` (“compile”) option just prevents the compiled representation from being run, thus behaving like a traditional compiler with output targeted to `/dev/null`. – amon Jun 01 '13 at 09:14
  • @amon, I didn't actually write anything about bytecodes or opcodes, was just highlighting the difference between an interpreted and compiled language. In a language like PHP, there can potentially be an `include` statement at any point in the code. Even if there is a syntax error in the included file, the program will run perfectly well until it reaches this file, at which point it will crash. – laurent Jun 01 '13 at 17:18
  • 1
    This is very different from a compiled language which will be entirely converted to bytecode before being executed. So, there's no need to "check the syntax" of a compiled language - if it builds it's ok, if not there's an error. An interpreted language however can run and still have syntax errors, which is why the extra `-c` flag makes sense for Ruby (since I assume it will check the full source tree, like an actual compiler) but not for compiled languages (which already have a compiler). – laurent Jun 01 '13 at 17:20
1

In agreement with @Rick-777, I would strongly recommend using go build. It performs additional checks that go fmt does not (ex: missing or unnecessary imports).

If you are worried about creating a binary in your source directory, you could always go build -o /dev/null to discard the output, which essentially reduces go build to a test that the code will build. That gets you syntax checking, among other things.

EDIT: note that go build doesn't generate a binary when building non-main packages, so you don't need the -o option.

burfl
  • 2,138
  • 2
  • 20
  • 18
0

Updated answer for those that don't want to settle for only checking with gofmt:

You can substitute gotype for go build to get just the front-end of the go compiler that validates both syntax and structure: https://godoc.org/golang.org/x/tools/cmd/gotype

It's comparative in speed to gofmt, but returns all the errors you'd get from go build.

The one caveat is that it appears to require other packages to be go installed, otherwise it doesn't find them. Not sure why this is.

robbles
  • 2,729
  • 1
  • 23
  • 30
0

golang syntax checker

Place the below code in a file called gochk in a bin dir and chmod 0755.

Then run gochk -- help

#!/bin/bash
#
# gochk v1.0 2017-03-15 - golang syntax checker - ekerner@ekerner.com
# see --help

# usage and version
if \
    test "$1" = "-?" || \
    test "$1" = "-h" || \
    test "$1" = "--help" || \
    test "$1" = "-v" || \
    test "$1" = "--version"
then
    echo "gochk v1.0 2017-03-15 - golang syntax checker - ekerner@ekerner.com"; echo
    echo "Usage:"
    echo "  $0 -?|-h|--help|-v|--version # show this"
    echo "  $0 [ file1.go [ file2.go . . . ] ] # syntax check"
    echo "If no args passed then *.go will be checked"; echo
    echo "Examples:"
    echo "  $0 --help # show this"
    echo "  $0 # syntax check *.go"
    echo "  $0 cmd/my-app/main.go handlers/*.go # syntax check list"; echo
    echo "Authors:"
    echo "  http://stackoverflow.com/users/233060/ekerner"
    echo "  http://stackoverflow.com/users/2437417/crazy-train"
    exit
fi

# default to .go files in cwd
gos=$@
if test $# -eq 0; then
    gos=$(ls -1 *.go 2>/dev/null)
    if test ${#gos[@]} -eq 0; then
        exit
    fi
fi

# test each one using gofmt
# credit to Crazy Train at
# http://stackoverflow.com/questions/16863014/is-there-a-command-line-tool-in-golang-to-only-check-syntax-of-my-source-code
#
for go in $gos; do
    gofmt -e "$go" >/dev/null
done
ekerner
  • 5,650
  • 1
  • 37
  • 31