Script for automatically generate conversions.

This commit is contained in:
Wojciech Tyczynski
2015-05-18 22:40:10 +02:00
parent c4ab34f7f9
commit 9a93206774
6 changed files with 95 additions and 48 deletions

View File

@@ -33,7 +33,7 @@ import (
"github.com/golang/glog"
)
func generateConversions(t *testing.T, version string) (bytes.Buffer, bytes.Buffer) {
func generateConversions(t *testing.T, version string) bytes.Buffer {
g := runtime.NewConversionGenerator(api.Scheme.Raw())
g.OverwritePackage(version, "")
g.OverwritePackage("api", "newer")
@@ -51,17 +51,14 @@ func generateConversions(t *testing.T, version string) (bytes.Buffer, bytes.Buff
if err := functionsWriter.Flush(); err != nil {
t.Fatalf("error while flushing writer")
}
var names bytes.Buffer
namesWriter := bufio.NewWriter(&names)
if err := g.WriteConversionFunctionNames(namesWriter); err != nil {
if err := g.RegisterConversionFunctions(functionsWriter); err != nil {
t.Fatalf("couldn't generate conversion function names: %v", err)
}
if err := namesWriter.Flush(); err != nil {
if err := functionsWriter.Flush(); err != nil {
t.Fatalf("error while flushing writer")
}
return functions, names
return functions
}
func readLinesUntil(t *testing.T, reader *bufio.Reader, stop string, buffer *bytes.Buffer) error {
@@ -85,7 +82,7 @@ func readLinesUntil(t *testing.T, reader *bufio.Reader, stop string, buffer *byt
return nil
}
func bufferExistingConversions(t *testing.T, fileName string) (bytes.Buffer, bytes.Buffer) {
func bufferExistingConversions(t *testing.T, fileName string) bytes.Buffer {
file, err := os.Open(fileName)
if err != nil {
t.Fatalf("couldn't open file %s", fileName)
@@ -103,18 +100,11 @@ func bufferExistingConversions(t *testing.T, fileName string) (bytes.Buffer, byt
if err := readLinesUntil(t, reader, functionsSuffix, &functions); err != nil {
t.Fatalf("error while parsing file: %v", err)
}
functionNamesPrefix := "\terr := newer.Scheme.AddGeneratedConversionFuncs(\n"
functionNamesSuffix := "\t)\n"
if err := readLinesUntil(t, reader, functionNamesPrefix, nil); err != nil {
t.Fatalf("error while parsing file: %v", err)
_, err = reader.ReadString('\n')
if err == nil || err != io.EOF {
t.Fatalf("end-of-file expected")
}
var names bytes.Buffer
if err := readLinesUntil(t, reader, functionNamesSuffix, &names); err != nil {
t.Fatalf("error while parsing file: %v", err)
}
return functions, names
return functions
}
func compareBuffers(t *testing.T, generatedFile string, existing, generated bytes.Buffer) bool {
@@ -150,20 +140,14 @@ func TestNoManualChangesToGenerateConversions(t *testing.T) {
for _, version := range versions {
fileName := fmt.Sprintf("../../pkg/api/%s/conversion_generated.go", version)
existingFunctions, existingNames := bufferExistingConversions(t, fileName)
generatedFunctions, generatedNames := generateConversions(t, version)
existingFunctions := bufferExistingConversions(t, fileName)
generatedFunctions := generateConversions(t, version)
functionsTxt := fmt.Sprintf("%s.functions.txt", version)
ioutil.WriteFile(functionsTxt, generatedFunctions.Bytes(), os.FileMode(0644))
namesTxt := fmt.Sprintf("%s.names.txt", version)
ioutil.WriteFile(namesTxt, generatedNames.Bytes(), os.FileMode(0644))
if ok := compareBuffers(t, functionsTxt, existingFunctions, generatedFunctions); ok {
os.Remove(functionsTxt)
}
if ok := compareBuffers(t, namesTxt, existingNames, generatedNames); ok {
os.Remove(namesTxt)
}
}
}

View File

@@ -29,7 +29,7 @@ import (
type ConversionGenerator interface {
GenerateConversionsForType(version string, reflection reflect.Type) error
WriteConversionFunctions(w io.Writer) error
WriteConversionFunctionNames(w io.Writer) error
RegisterConversionFunctions(w io.Writer) error
OverwritePackage(pkg, overwrite string)
}
@@ -263,7 +263,22 @@ func (g *conversionGenerator) WriteConversionFunctions(w io.Writer) error {
return nil
}
func (g *conversionGenerator) WriteConversionFunctionNames(w io.Writer) error {
func (g *conversionGenerator) writeRegisterHeader(b *buffer, indent int) {
b.addLine("func init() {\n", indent)
b.addLine("err := newer.Scheme.AddGeneratedConversionFuncs(\n", indent+1)
}
func (g *conversionGenerator) writeRegisterFooter(b *buffer, indent int) {
b.addLine(")\n", indent+1)
b.addLine("if err != nil {\n", indent+1)
b.addLine("// If one of the conversion functions is malformed, detect it immediately.\n", indent+2)
b.addLine("panic(err)\n", indent+2)
b.addLine("}\n", indent+1)
b.addLine("}\n", indent)
b.addLine("\n", indent)
}
func (g *conversionGenerator) RegisterConversionFunctions(w io.Writer) error {
// Write conversion function names alphabetically ordered.
var names []string
for inType, outType := range g.convertibles {
@@ -273,10 +288,12 @@ func (g *conversionGenerator) WriteConversionFunctionNames(w io.Writer) error {
sort.Strings(names)
buffer := newBuffer()
indent := 2
indent := 0
g.writeRegisterHeader(buffer, indent)
for _, name := range names {
buffer.addLine(fmt.Sprintf("%s,\n", name), indent)
buffer.addLine(fmt.Sprintf("%s,\n", name), indent+2)
}
g.writeRegisterFooter(buffer, indent)
if err := buffer.flushLines(w); err != nil {
return err
}