Refer to the script comments for details on how to use this script.
Code: Select all
#
# Name: Go Plus Script
#
# Author: Jussi Jumppanen
#
# Language: Python
#
# Description: This script will run gofmt, goimports, golint, go vet and
# go build on the current file and capture any error output produced.
#
# The script will run the following Go command on the current file
# in the order listed:
#
# gofmt
# goimports
# golint
# go vet
# go build
#
# If any errors are detected they will be reported to the user with
# the line number, error message and file name allowing the user to
# quickly navigate to the error.
#
# This macro assumes the imports, vet and lint packages have been
# downloaded, built and correctly installed:
#
# lint - https://github.com/golang/lint
# imports - http://godoc.org/code.google.com/p/go.tools/cmd/goimports
# vet - http://godoc.org/code.google.com/p/go.tools/cmd/vet
#
# To make this script run on file save just use the Options, Editor Options
# menu and in the Triggers panel set this as the File Save Portfix script:
#
# $zud\zScript\go_plus.py
#
import os
import zeus
import os.path
def goplus_trigger():
# get the document type for the current file
document_type = zeus.macro_tag("$DTD")
if (document_type != "Go Document Type"):
# ignore this file as it is not a Go document type
return 1
# macro only works for documents
document = zeus.is_document()
# macro only works for read/write documents.
locked = zeus.is_read_only()
# macro only works for named documents.
named = zeus.is_named()
if (locked == 1) or (document == 0) or (named == 0):
# can't run the format on current document
zeus.message("This macro only works with named, writable Go documents.")
zeus.beep()
return 0
# the details of the current document
file_base = zeus.macro_tag("$f")
file_name = zeus.macro_tag("$fn")
# the output file name
file_output = file_name + ".ztow"
# the compiler error name
file_error = file_name + ".zerr"
# remove any previous output file
if os.access(file_output, os.F_OK):
os.remove(file_output)
# remove any previous error file
if os.access(file_error, os.F_OK):
os.remove(file_error)
result = 0
if result == 0:
# run gofmt
result = go_fmt(file_name, file_output)
if result == 0:
# run goimports command
result = go_imports(file_name, file_output)
if result == 0:
# run go lint command
result = go_lint(file_name, file_output)
if result == 0:
# run go vet command
result = go_vet(file_name, file_output)
if result == 0:
# run go build command
result = go_build(file_name, file_output)
if result == 0:
zeus.message("File: '" + file_base + "' save completed.")
def go_build(file_name, file_output):
# the go build command
return run_cmd("go build", file_name, file_output)
def go_fmt(file_name, file_output):
# -------------------------------------------------------------------------
# -- usage: gofmt [flags] [path ...]
# -------------------------------------------------------------------------
# -- -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
# -- -w=false: write result to (source) file instead of stdout
# -------------------------------------------------------------------------
# the gofmt command
return run_cmd("gofmt.exe -w=true -e=true", file_name, file_output)
def go_imports(file_name, file_output):
# the goimports command
return run_cmd("goimports.exe -w=true", file_name, file_output)
def go_lint(file_name, file_output):
# the golint command
return run_cmd("golint.exe", file_name, file_output)
def go_vet(file_name, file_output):
# the goimports command
return run_cmd("go vet", file_name, file_output)
def check_file_errors(file_errors):
# see if any output was produced
have_errors = 0
if (os.path.isfile(file_errors)):
statinfo = os.stat(file_errors)
if statinfo.st_size > 0:
have_errors = 1
return have_errors
def check_lfn(file_name):
# check if file contains any whitespace
if (file_name.find(' ') <> -1):
# add quotes to the output file name
file_name = '"' + file_name + '"'
return file_name
def run_cmd(cmd, file_name, file_errors):
# run the command as a DOS command in hidden window and wait for it to finish
flags = 16+32
# check all files for LFN details and pipe stdout, stderr to the errors file
cmd = cmd + " " + check_lfn(file_name) + " > " + check_lfn(file_errors) + " 2>&1 "
# run the command
result = zeus.system(cmd, "", flags)
# reload the file in case it was changed by the command
zeus.FileReloadCurrent()
# see if any output was produced
have_errors = check_file_errors(file_errors)
#zeus.message_box(0, cmd, result)
# see if there where any errors runninf the command
if (result != 0) or (have_errors != 0):
# see if we have and error files
if have_errors:
# open the error file in compiler output window
zeus.file_open_compiler(file_errors, cmd, file_name)
else:
# make sure the user will see the error
if zeus.is_debug_enabled() == 0:
zeus.debug_enable()
# log the command to the debug window
zeus.debug_output(cmd + "\n\n" + "Error executing the 'Go Plus' script!\n")
# set capture flags
flags = 1+32+2+4
# run the format again but this time capture the error output
zeus.system(cmd, "", flags)
# we have errors
result = 1;
# on success we return zero
return result
goplus_trigger() # run the macro