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.
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
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
.
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/
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.
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 install
ed, otherwise it doesn't find them. Not sure why this is.
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