Merge pull request #8443 from wojtek-t/conversion_improvements

Script for regenerate auto-generated conversions.
This commit is contained in:
Tim Hockin 2015-05-18 17:24:08 -07:00
commit 2307350d1b
6 changed files with 95 additions and 48 deletions

View File

@ -34,7 +34,6 @@ import (
var ( var (
functionDest = flag.StringP("funcDest", "f", "-", "Output for conversion functions; '-' means stdout") functionDest = flag.StringP("funcDest", "f", "-", "Output for conversion functions; '-' means stdout")
namesDest = flag.StringP("nameDest", "n", "-", "Output for function names; '-' means stdout")
version = flag.StringP("version", "v", "v1beta3", "Version for conversion.") version = flag.StringP("version", "v", "v1beta3", "Version for conversion.")
) )
@ -53,21 +52,11 @@ func main() {
defer file.Close() defer file.Close()
funcOut = file funcOut = file
} }
var nameOut io.Writer
if *namesDest == "-" {
nameOut = os.Stdout
} else {
file, err := os.Create(*namesDest)
if err != nil {
glog.Fatalf("Couldn't open %v: %v", *functionDest, err)
}
defer file.Close()
nameOut = file
}
generator := pkg_runtime.NewConversionGenerator(api.Scheme.Raw()) generator := pkg_runtime.NewConversionGenerator(api.Scheme.Raw())
// TODO(wojtek-t): Change the overwrites to a flag. // TODO(wojtek-t): Change the overwrites to a flag.
generator.OverwritePackage(*version, "") generator.OverwritePackage(*version, "")
// TODO(wojtek-t): Get rid of this overwrite.
generator.OverwritePackage("api", "newer") generator.OverwritePackage("api", "newer")
for _, knownType := range api.Scheme.KnownTypes(*version) { for _, knownType := range api.Scheme.KnownTypes(*version) {
if err := generator.GenerateConversionsForType(*version, knownType); err != nil { if err := generator.GenerateConversionsForType(*version, knownType); err != nil {
@ -77,7 +66,7 @@ func main() {
if err := generator.WriteConversionFunctions(funcOut); err != nil { if err := generator.WriteConversionFunctions(funcOut); err != nil {
glog.Fatalf("Error while writing conversion functions: %v", err) glog.Fatalf("Error while writing conversion functions: %v", err)
} }
if err := generator.WriteConversionFunctionNames(nameOut); err != nil { if err := generator.RegisterConversionFunctions(funcOut); err != nil {
glog.Fatalf("Error while writing conversion functions: %v", err) glog.Fatalf("Error while writing conversion functions: %v", err)
} }
} }

View File

@ -0,0 +1,57 @@
#!/bin/bash
# Copyright 2015 The Kubernetes Authors All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# Script to fetch latest swagger spec.
# Puts the updated spec at swagger-spec/
set -o errexit
set -o nounset
set -o pipefail
function generate_version() {
local version=$1
local TMPFILE="/tmp/conversion_generated.$(date +%s).go"
echo "Generating for version ${version}"
sed 's/YEAR/2015/' hooks/boilerplate.go.txt > $TMPFILE
cat >> $TMPFILE <<EOF
package ${version}
import (
"reflect"
newer "github.com/GoogleCloudPlatform/kubernetes/pkg/api"
"github.com/GoogleCloudPlatform/kubernetes/pkg/api/resource"
"github.com/GoogleCloudPlatform/kubernetes/pkg/conversion"
)
// AUTO-GENERATED FUNCTIONS START HERE
EOF
go run cmd/kube-conversion/conversion.go -v ${version} -f - >> $TMPFILE
cat >> $TMPFILE <<EOF
// AUTO-GENERATED FUNCTIONS END HERE
EOF
mv $TMPFILE pkg/api/${version}/conversion_generated.go
}
VERSIONS="v1beta3 v1"
for ver in $VERSIONS; do
generate_version "${ver}"
done

View File

@ -4475,8 +4475,6 @@ func convert_api_VolumeSource_To_v1_VolumeSource(in *newer.VolumeSource, out *Vo
return nil return nil
} }
// AUTO-GENERATED FUNCTIONS END HERE
func init() { func init() {
err := newer.Scheme.AddGeneratedConversionFuncs( err := newer.Scheme.AddGeneratedConversionFuncs(
convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource, convert_api_AWSElasticBlockStoreVolumeSource_To_v1_AWSElasticBlockStoreVolumeSource,
@ -4705,3 +4703,5 @@ func init() {
panic(err) panic(err)
} }
} }
// AUTO-GENERATED FUNCTIONS END HERE

View File

@ -4289,8 +4289,6 @@ func convert_api_VolumeSource_To_v1beta3_VolumeSource(in *newer.VolumeSource, ou
return nil return nil
} }
// AUTO-GENERATED FUNCTIONS END HERE
func init() { func init() {
err := newer.Scheme.AddGeneratedConversionFuncs( err := newer.Scheme.AddGeneratedConversionFuncs(
convert_api_AWSElasticBlockStoreVolumeSource_To_v1beta3_AWSElasticBlockStoreVolumeSource, convert_api_AWSElasticBlockStoreVolumeSource_To_v1beta3_AWSElasticBlockStoreVolumeSource,
@ -4517,3 +4515,5 @@ func init() {
panic(err) panic(err)
} }
} }
// AUTO-GENERATED FUNCTIONS END HERE

View File

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

View File

@ -29,7 +29,7 @@ import (
type ConversionGenerator interface { type ConversionGenerator interface {
GenerateConversionsForType(version string, reflection reflect.Type) error GenerateConversionsForType(version string, reflection reflect.Type) error
WriteConversionFunctions(w io.Writer) error WriteConversionFunctions(w io.Writer) error
WriteConversionFunctionNames(w io.Writer) error RegisterConversionFunctions(w io.Writer) error
OverwritePackage(pkg, overwrite string) OverwritePackage(pkg, overwrite string)
} }
@ -263,7 +263,22 @@ func (g *conversionGenerator) WriteConversionFunctions(w io.Writer) error {
return nil 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. // Write conversion function names alphabetically ordered.
var names []string var names []string
for inType, outType := range g.convertibles { for inType, outType := range g.convertibles {
@ -273,10 +288,12 @@ func (g *conversionGenerator) WriteConversionFunctionNames(w io.Writer) error {
sort.Strings(names) sort.Strings(names)
buffer := newBuffer() buffer := newBuffer()
indent := 2 indent := 0
g.writeRegisterHeader(buffer, indent)
for _, name := range names { 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 { if err := buffer.flushLines(w); err != nil {
return err return err
} }