git subrepo clone (merge) https://github.com/kubernetes-incubator/metrics-server.git metrics-server
subrepo:
subdir: "metrics-server"
merged: "92d8412"
upstream:
origin: "https://github.com/kubernetes-incubator/metrics-server.git"
branch: "master"
commit: "92d8412"
git-subrepo:
version: "0.4.0"
origin: "???"
commit: "???"
diff --git a/metrics-server/vendor/k8s.io/gengo/generator/execute.go b/metrics-server/vendor/k8s.io/gengo/generator/execute.go
new file mode 100644
index 0000000..38dffff
--- /dev/null
+++ b/metrics-server/vendor/k8s.io/gengo/generator/execute.go
@@ -0,0 +1,312 @@
+/*
+Copyright 2015 The Kubernetes Authors.
+
+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.
+*/
+
+package generator
+
+import (
+ "bytes"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "golang.org/x/tools/imports"
+ "k8s.io/gengo/namer"
+ "k8s.io/gengo/types"
+
+ "github.com/golang/glog"
+)
+
+func errs2strings(errors []error) []string {
+ strs := make([]string, len(errors))
+ for i := range errors {
+ strs[i] = errors[i].Error()
+ }
+ return strs
+}
+
+// ExecutePackages runs the generators for every package in 'packages'. 'outDir'
+// is the base directory in which to place all the generated packages; it
+// should be a physical path on disk, not an import path. e.g.:
+// /path/to/home/path/to/gopath/src/
+// Each package has its import path already, this will be appended to 'outDir'.
+func (c *Context) ExecutePackages(outDir string, packages Packages) error {
+ var errors []error
+ for _, p := range packages {
+ if err := c.ExecutePackage(outDir, p); err != nil {
+ errors = append(errors, err)
+ }
+ }
+ if len(errors) > 0 {
+ return fmt.Errorf("some packages had errors:\n%v\n", strings.Join(errs2strings(errors), "\n"))
+ }
+ return nil
+}
+
+type DefaultFileType struct {
+ Format func([]byte) ([]byte, error)
+ Assemble func(io.Writer, *File)
+}
+
+func (ft DefaultFileType) AssembleFile(f *File, pathname string) error {
+ glog.V(2).Infof("Assembling file %q", pathname)
+ destFile, err := os.Create(pathname)
+ if err != nil {
+ return err
+ }
+ defer destFile.Close()
+
+ b := &bytes.Buffer{}
+ et := NewErrorTracker(b)
+ ft.Assemble(et, f)
+ if et.Error() != nil {
+ return et.Error()
+ }
+ if formatted, err := ft.Format(b.Bytes()); err != nil {
+ err = fmt.Errorf("unable to format file %q (%v).", pathname, err)
+ // Write the file anyway, so they can see what's going wrong and fix the generator.
+ if _, err2 := destFile.Write(b.Bytes()); err2 != nil {
+ return err2
+ }
+ return err
+ } else {
+ _, err = destFile.Write(formatted)
+ return err
+ }
+}
+
+func (ft DefaultFileType) VerifyFile(f *File, pathname string) error {
+ glog.V(2).Infof("Verifying file %q", pathname)
+ friendlyName := filepath.Join(f.PackageName, f.Name)
+ b := &bytes.Buffer{}
+ et := NewErrorTracker(b)
+ ft.Assemble(et, f)
+ if et.Error() != nil {
+ return et.Error()
+ }
+ formatted, err := ft.Format(b.Bytes())
+ if err != nil {
+ return fmt.Errorf("unable to format the output for %q: %v", friendlyName, err)
+ }
+ existing, err := ioutil.ReadFile(pathname)
+ if err != nil {
+ return fmt.Errorf("unable to read file %q for comparison: %v", friendlyName, err)
+ }
+ if bytes.Compare(formatted, existing) == 0 {
+ return nil
+ }
+ // Be nice and find the first place where they differ
+ i := 0
+ for i < len(formatted) && i < len(existing) && formatted[i] == existing[i] {
+ i++
+ }
+ eDiff, fDiff := existing[i:], formatted[i:]
+ if len(eDiff) > 100 {
+ eDiff = eDiff[:100]
+ }
+ if len(fDiff) > 100 {
+ fDiff = fDiff[:100]
+ }
+ return fmt.Errorf("output for %q differs; first existing/expected diff: \n %q\n %q", friendlyName, string(eDiff), string(fDiff))
+}
+
+func assembleGolangFile(w io.Writer, f *File) {
+ w.Write(f.Header)
+ fmt.Fprintf(w, "package %v\n\n", f.PackageName)
+
+ if len(f.Imports) > 0 {
+ fmt.Fprint(w, "import (\n")
+ for i := range f.Imports {
+ if strings.Contains(i, "\"") {
+ // they included quotes, or are using the
+ // `name "path/to/pkg"` format.
+ fmt.Fprintf(w, "\t%s\n", i)
+ } else {
+ fmt.Fprintf(w, "\t%q\n", i)
+ }
+ }
+ fmt.Fprint(w, ")\n\n")
+ }
+
+ if f.Vars.Len() > 0 {
+ fmt.Fprint(w, "var (\n")
+ w.Write(f.Vars.Bytes())
+ fmt.Fprint(w, ")\n\n")
+ }
+
+ if f.Consts.Len() > 0 {
+ fmt.Fprint(w, "const (\n")
+ w.Write(f.Consts.Bytes())
+ fmt.Fprint(w, ")\n\n")
+ }
+
+ w.Write(f.Body.Bytes())
+}
+
+func importsWrapper(src []byte) ([]byte, error) {
+ return imports.Process("", src, nil)
+}
+
+func NewGolangFile() *DefaultFileType {
+ return &DefaultFileType{
+ Format: importsWrapper,
+ Assemble: assembleGolangFile,
+ }
+}
+
+// format should be one line only, and not end with \n.
+func addIndentHeaderComment(b *bytes.Buffer, format string, args ...interface{}) {
+ if b.Len() > 0 {
+ fmt.Fprintf(b, "\n// "+format+"\n", args...)
+ } else {
+ fmt.Fprintf(b, "// "+format+"\n", args...)
+ }
+}
+
+func (c *Context) filteredBy(f func(*Context, *types.Type) bool) *Context {
+ c2 := *c
+ c2.Order = []*types.Type{}
+ for _, t := range c.Order {
+ if f(c, t) {
+ c2.Order = append(c2.Order, t)
+ }
+ }
+ return &c2
+}
+
+// make a new context; inheret c.Namers, but add on 'namers'. In case of a name
+// collision, the namer in 'namers' wins.
+func (c *Context) addNameSystems(namers namer.NameSystems) *Context {
+ if namers == nil {
+ return c
+ }
+ c2 := *c
+ // Copy the existing name systems so we don't corrupt a parent context
+ c2.Namers = namer.NameSystems{}
+ for k, v := range c.Namers {
+ c2.Namers[k] = v
+ }
+
+ for name, namer := range namers {
+ c2.Namers[name] = namer
+ }
+ return &c2
+}
+
+// ExecutePackage executes a single package. 'outDir' is the base directory in
+// which to place the package; it should be a physical path on disk, not an
+// import path. e.g.: '/path/to/home/path/to/gopath/src/' The package knows its
+// import path already, this will be appended to 'outDir'.
+func (c *Context) ExecutePackage(outDir string, p Package) error {
+ path := filepath.Join(outDir, p.Path())
+ glog.V(2).Infof("Processing package %q, disk location %q", p.Name(), path)
+ // Filter out any types the *package* doesn't care about.
+ packageContext := c.filteredBy(p.Filter)
+ os.MkdirAll(path, 0755)
+ files := map[string]*File{}
+ for _, g := range p.Generators(packageContext) {
+ // Filter out types the *generator* doesn't care about.
+ genContext := packageContext.filteredBy(g.Filter)
+ // Now add any extra name systems defined by this generator
+ genContext = genContext.addNameSystems(g.Namers(genContext))
+
+ fileType := g.FileType()
+ if len(fileType) == 0 {
+ return fmt.Errorf("generator %q must specify a file type", g.Name())
+ }
+ f := files[g.Filename()]
+ if f == nil {
+ // This is the first generator to reference this file, so start it.
+ f = &File{
+ Name: g.Filename(),
+ FileType: fileType,
+ PackageName: p.Name(),
+ Header: p.Header(g.Filename()),
+ Imports: map[string]struct{}{},
+ }
+ files[f.Name] = f
+ } else {
+ if f.FileType != g.FileType() {
+ return fmt.Errorf("file %q already has type %q, but generator %q wants to use type %q", f.Name, f.FileType, g.Name(), g.FileType())
+ }
+ }
+
+ if vars := g.PackageVars(genContext); len(vars) > 0 {
+ addIndentHeaderComment(&f.Vars, "Package-wide variables from generator %q.", g.Name())
+ for _, v := range vars {
+ if _, err := fmt.Fprintf(&f.Vars, "%s\n", v); err != nil {
+ return err
+ }
+ }
+ }
+ if consts := g.PackageConsts(genContext); len(consts) > 0 {
+ addIndentHeaderComment(&f.Consts, "Package-wide consts from generator %q.", g.Name())
+ for _, v := range consts {
+ if _, err := fmt.Fprintf(&f.Consts, "%s\n", v); err != nil {
+ return err
+ }
+ }
+ }
+ if err := genContext.executeBody(&f.Body, g); err != nil {
+ return err
+ }
+ if imports := g.Imports(genContext); len(imports) > 0 {
+ for _, i := range imports {
+ f.Imports[i] = struct{}{}
+ }
+ }
+ }
+
+ var errors []error
+ for _, f := range files {
+ finalPath := filepath.Join(path, f.Name)
+ assembler, ok := c.FileTypes[f.FileType]
+ if !ok {
+ return fmt.Errorf("the file type %q registered for file %q does not exist in the context", f.FileType, f.Name)
+ }
+ var err error
+ if c.Verify {
+ err = assembler.VerifyFile(f, finalPath)
+ } else {
+ err = assembler.AssembleFile(f, finalPath)
+ }
+ if err != nil {
+ errors = append(errors, err)
+ }
+ }
+ if len(errors) > 0 {
+ return fmt.Errorf("errors in package %q:\n%v\n", p.Path(), strings.Join(errs2strings(errors), "\n"))
+ }
+ return nil
+}
+
+func (c *Context) executeBody(w io.Writer, generator Generator) error {
+ et := NewErrorTracker(w)
+ if err := generator.Init(c, et); err != nil {
+ return err
+ }
+ for _, t := range c.Order {
+ if err := generator.GenerateType(c, t, et); err != nil {
+ return err
+ }
+ }
+ if err := generator.Finalize(c, et); err != nil {
+ return err
+ }
+ return et.Error()
+}