diff --git a/Makefile b/Makefile index acf5363a00b..b71fa046b99 100644 --- a/Makefile +++ b/Makefile @@ -89,9 +89,7 @@ parser: make -C go/vt/sqlparser visitor: - go build -o visitorgen go/visitorgen/main/main.go - ./visitorgen -input=go/vt/sqlparser/ast.go -output=$(REWRITER) - rm ./visitorgen + go generate go/vt/sqlparser/rewriter.go # To pass extra flags, run test.go manually. # For example: go run test.go -docker=false -- --extra-flag diff --git a/go/vt/sqlparser/rewriter.go b/go/vt/sqlparser/rewriter.go index 28d5ba52688..2f6c22879fe 100644 --- a/go/vt/sqlparser/rewriter.go +++ b/go/vt/sqlparser/rewriter.go @@ -2,7 +2,7 @@ package sqlparser -//go:generate make visitor +//go:generate go run visitorgen/main -input=ast.go -output=rewriter.go import ( "reflect" diff --git a/go/visitorgen/ast_walker.go b/go/vt/sqlparser/visitorgen/ast_walker.go similarity index 100% rename from go/visitorgen/ast_walker.go rename to go/vt/sqlparser/visitorgen/ast_walker.go diff --git a/go/visitorgen/ast_walker_test.go b/go/vt/sqlparser/visitorgen/ast_walker_test.go similarity index 100% rename from go/visitorgen/ast_walker_test.go rename to go/vt/sqlparser/visitorgen/ast_walker_test.go diff --git a/go/visitorgen/main/main.go b/go/vt/sqlparser/visitorgen/main/main.go similarity index 67% rename from go/visitorgen/main/main.go rename to go/vt/sqlparser/visitorgen/main/main.go index ae09ad7efdf..5b53b3d268f 100644 --- a/go/visitorgen/main/main.go +++ b/go/vt/sqlparser/visitorgen/main/main.go @@ -17,44 +17,46 @@ limitations under the License. package main import ( + "bytes" "flag" "fmt" "go/parser" "go/token" + "io/ioutil" "os" - "vitess.io/vitess/go/visitorgen" + "vitess.io/vitess/go/exit" + "vitess.io/vitess/go/vt/log" + + "vitess.io/vitess/go/vt/sqlparser/visitorgen" ) var ( inputFile = flag.String("input", "", "input file to use") outputFile = flag.String("output", "", "output file") + compare = flag.Bool("compareOnly", false, "instead of writing to the output file, compare if the generated visitor is still valid for this ast.go") ) const usage = `Usage of visitorgen: -go run go/visitorgen/main/main.go -input=/path/to/ast.go -output=/path/to/rewriter.go +go run /path/to/visitorgen/main -input=/path/to/ast.go -output=/path/to/rewriter.go ` func main() { - flag.Usage = func() { - os.Stderr.WriteString(usage) - os.Stderr.WriteString("\nOptions:\n") - flag.PrintDefaults() - - } + defer exit.Recover() + flag.Usage = printUsage flag.Parse() if *inputFile == "" || *outputFile == "" { - fmt.Println("> " + *inputFile) - fmt.Println("> " + *outputFile) - panic("need input and output file") + printUsage() + exit.Return(1) } fs := token.NewFileSet() file, err := parser.ParseFile(fs, *inputFile, nil, parser.DeclarationErrors) if err != nil { - panic(err) + log.Error(err) + exit.Return(1) } astWalkResult := visitorgen.Walk(file) @@ -64,49 +66,45 @@ func main() { replacementMethods := visitorgen.EmitReplacementMethods(vd) typeSwitch := visitorgen.EmitTypeSwitches(vd) - fw := newFileWriter(*outputFile) - defer fw.Close() - - fw.writeln(fileHeader) - fw.writeln(replacementMethods) - fw.write(applyHeader) - fw.writeln(typeSwitch) - fw.writeln(fileFooter) -} - -type fileWriter struct { - file *os.File -} - -func newFileWriter(file string) *fileWriter { - f, err := os.Create(file) - if err != nil { - panic(err) + b := &bytes.Buffer{} + fmt.Fprint(b, fileHeader) + fmt.Fprintln(b) + fmt.Fprintln(b, replacementMethods) + fmt.Fprint(b, applyHeader) + fmt.Fprintln(b, typeSwitch) + fmt.Fprintln(b, fileFooter) + + if *compare { + currentFile, err := ioutil.ReadFile(*outputFile) + if err != nil { + log.Error(err) + exit.Return(1) + } + if !bytes.Equal(b.Bytes(), currentFile) { + fmt.Println("rewriter needs to be re-generated: go generate " + *outputFile) + exit.Return(1) + } + } else { + err = ioutil.WriteFile(*outputFile, b.Bytes(), 0644) + if err != nil { + log.Error(err) + exit.Return(1) + } } - return &fileWriter{file: f} -} -func (fw *fileWriter) writeln(s string) { - fw.write(s) - fw.write("\n") -} - -func (fw *fileWriter) write(s string) { - _, err := fw.file.WriteString(s) - if err != nil { - panic(err) - } } -func (fw *fileWriter) Close() { - fw.file.Close() +func printUsage() { + os.Stderr.WriteString(usage) + os.Stderr.WriteString("\nOptions:\n") + flag.PrintDefaults() } const fileHeader = `// Code generated by visitorgen/main/main.go. DO NOT EDIT. package sqlparser -//go:generate make visitor +//go:generate go run visitorgen/main -input=ast.go -output=rewriter.go import ( "reflect" diff --git a/go/visitorgen/sast.go b/go/vt/sqlparser/visitorgen/sast.go similarity index 100% rename from go/visitorgen/sast.go rename to go/vt/sqlparser/visitorgen/sast.go diff --git a/go/visitorgen/struct_producer.go b/go/vt/sqlparser/visitorgen/struct_producer.go similarity index 100% rename from go/visitorgen/struct_producer.go rename to go/vt/sqlparser/visitorgen/struct_producer.go diff --git a/go/visitorgen/struct_producer_test.go b/go/vt/sqlparser/visitorgen/struct_producer_test.go similarity index 100% rename from go/visitorgen/struct_producer_test.go rename to go/vt/sqlparser/visitorgen/struct_producer_test.go diff --git a/go/visitorgen/transformer.go b/go/vt/sqlparser/visitorgen/transformer.go similarity index 100% rename from go/visitorgen/transformer.go rename to go/vt/sqlparser/visitorgen/transformer.go diff --git a/go/visitorgen/transformer_test.go b/go/vt/sqlparser/visitorgen/transformer_test.go similarity index 100% rename from go/visitorgen/transformer_test.go rename to go/vt/sqlparser/visitorgen/transformer_test.go diff --git a/go/visitorgen/visitor_emitter.go b/go/vt/sqlparser/visitorgen/visitor_emitter.go similarity index 100% rename from go/visitorgen/visitor_emitter.go rename to go/vt/sqlparser/visitorgen/visitor_emitter.go diff --git a/go/visitorgen/visitor_emitter_test.go b/go/vt/sqlparser/visitorgen/visitor_emitter_test.go similarity index 100% rename from go/visitorgen/visitor_emitter_test.go rename to go/vt/sqlparser/visitorgen/visitor_emitter_test.go diff --git a/go/visitorgen/visitorgen.go b/go/vt/sqlparser/visitorgen/visitorgen.go similarity index 100% rename from go/visitorgen/visitorgen.go rename to go/vt/sqlparser/visitorgen/visitorgen.go diff --git a/misc/git/hooks/visitorgen b/misc/git/hooks/visitorgen index 7eb1c41360f..65c04d613db 100755 --- a/misc/git/hooks/visitorgen +++ b/misc/git/hooks/visitorgen @@ -15,11 +15,4 @@ # this script, which should run before committing code, makes sure that the visitor is re-generated when the ast changes -make visitor REWRITER=tmp_rewriter.go -if ! cmp -s "tmp_rewriter.go" "go/vt/sqlparser/rewriter.go"; then - echo "The ast.go has changed, but not rewriter.go" - echo "You should 'make visitor' to update the generated rewriter" - rm -f tmp_rewriter.go - exit 1 -fi -rm -f tmp_rewriter.go \ No newline at end of file +go run ./go/vt/sqlparser/visitorgen/main -compareOnly=true -input=go/vt/sqlparser/ast.go -output=go/vt/sqlparser/rewriter.go \ No newline at end of file diff --git a/test/config.json b/test/config.json index a61ce65eab0..e493c43cac8 100644 --- a/test/config.json +++ b/test/config.json @@ -38,6 +38,17 @@ "RetryMax": 1, "Tags": [] }, + "check_make_visitor": { + "File": "", + "Args": [], + "Command": [ + "misc/git/hooks/visitorgen" + ], + "Manual": false, + "Shard": 5, + "RetryMax": 1, + "Tags": [] + }, "java": { "File": "", "Args": [],