mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-08 11:38:15 +00:00
Merge pull request #3909 from jbeda/hyperkube
Create new hyperkube package
This commit is contained in:
commit
8723ee9ab5
30
pkg/hyperkube/doc.go
Normal file
30
pkg/hyperkube/doc.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 Google Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Package hyperkube is a framework for kubernetes server components. It
|
||||||
|
// allows us to combine all of the kubernetes server components into a single
|
||||||
|
// binary where the user selects which components to run in any individual
|
||||||
|
// process.
|
||||||
|
//
|
||||||
|
// Currently, only one server component can be run at once. As such there is
|
||||||
|
// no need to harmonize flags or identify logs across the various servers. In
|
||||||
|
// the future we will support launching and running many servers -- either by
|
||||||
|
// managing processes or running in-proc.
|
||||||
|
//
|
||||||
|
// This package is inspired by https://github.com/spf13/cobra. However, as
|
||||||
|
// the eventual goal is to run *multiple* servers from one call, a new package
|
||||||
|
// was needed.
|
||||||
|
package hyperkube
|
184
pkg/hyperkube/hyperkube.go
Normal file
184
pkg/hyperkube/hyperkube.go
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 Google Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package hyperkube
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
|
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
// HyperKube represents a single binary that can morph/manage into multiple
|
||||||
|
// servers.
|
||||||
|
type HyperKube struct {
|
||||||
|
Name string // The executable name, used for help and soft-link invocation
|
||||||
|
Long string // A long description of the binary. It will be world wrapped before output.
|
||||||
|
|
||||||
|
servers []Server
|
||||||
|
baseFlags *pflag.FlagSet
|
||||||
|
out io.Writer
|
||||||
|
helpFlagVal bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// AddServer adds a server to the HyperKube object.
|
||||||
|
func (hk *HyperKube) AddServer(s *Server) {
|
||||||
|
hk.servers = append(hk.servers, *s)
|
||||||
|
hk.servers[len(hk.servers)-1].hk = hk
|
||||||
|
}
|
||||||
|
|
||||||
|
// FindServer will find a specific server named name.
|
||||||
|
func (hk *HyperKube) FindServer(name string) (*Server, error) {
|
||||||
|
for _, s := range hk.servers {
|
||||||
|
if s.Name() == name {
|
||||||
|
return &s, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("Server not found: %s", name)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Servers returns a list of all of the registred servers
|
||||||
|
func (hk *HyperKube) Servers() []Server {
|
||||||
|
return hk.servers
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flags returns a flagset for "global" flags.
|
||||||
|
func (hk *HyperKube) Flags() *pflag.FlagSet {
|
||||||
|
if hk.baseFlags == nil {
|
||||||
|
hk.baseFlags = pflag.NewFlagSet(hk.Name, pflag.ContinueOnError)
|
||||||
|
hk.baseFlags.SetOutput(ioutil.Discard)
|
||||||
|
hk.baseFlags.BoolVarP(&hk.helpFlagVal, "help", "h", false, "help for "+hk.Name)
|
||||||
|
|
||||||
|
// These will add all of the "global" flags (defined with both the
|
||||||
|
// flag and pflag packages) to the new flag set we have.
|
||||||
|
util.AddFlagSetToPFlagSet(flag.CommandLine, hk.baseFlags)
|
||||||
|
util.AddPFlagSetToPFlagSet(pflag.CommandLine, hk.baseFlags)
|
||||||
|
|
||||||
|
}
|
||||||
|
return hk.baseFlags
|
||||||
|
}
|
||||||
|
|
||||||
|
// Out returns the io.Writer that is used for all usage/error information
|
||||||
|
func (hk *HyperKube) Out() io.Writer {
|
||||||
|
if hk.out == nil {
|
||||||
|
hk.out = os.Stderr
|
||||||
|
}
|
||||||
|
return hk.out
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetOut sets the output writer for all usage/error information
|
||||||
|
func (hk *HyperKube) SetOut(w io.Writer) {
|
||||||
|
hk.out = w
|
||||||
|
}
|
||||||
|
|
||||||
|
// Print is a convenience method to Print to the defined output
|
||||||
|
func (hk *HyperKube) Print(i ...interface{}) {
|
||||||
|
fmt.Fprint(hk.Out(), i...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Println is a convenience method to Println to the defined output
|
||||||
|
func (hk *HyperKube) Println(i ...interface{}) {
|
||||||
|
str := fmt.Sprintln(i...)
|
||||||
|
hk.Print(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Printf is a convenience method to Printf to the defined output
|
||||||
|
func (hk *HyperKube) Printf(format string, i ...interface{}) {
|
||||||
|
str := fmt.Sprintf(format, i...)
|
||||||
|
hk.Print(str)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run the server. This will pick the appropriate server and run it.
|
||||||
|
func (hk *HyperKube) Run(args []string) error {
|
||||||
|
// If we are called directly, parse all flags up to the first real
|
||||||
|
// argument. That should be the server to run.
|
||||||
|
baseCommand := path.Base(args[0])
|
||||||
|
serverName := baseCommand
|
||||||
|
if serverName == hk.Name {
|
||||||
|
args = args[1:]
|
||||||
|
|
||||||
|
baseFlags := hk.Flags()
|
||||||
|
baseFlags.SetInterspersed(false) // Only parse flags up to the next real command
|
||||||
|
err := baseFlags.Parse(args)
|
||||||
|
if err != nil || hk.helpFlagVal {
|
||||||
|
if err != nil {
|
||||||
|
hk.Println("Error:", err)
|
||||||
|
}
|
||||||
|
hk.Usage()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
args = baseFlags.Args()
|
||||||
|
if len(args) > 0 && len(args[0]) > 0 {
|
||||||
|
serverName = args[0]
|
||||||
|
baseCommand = baseCommand + " " + serverName
|
||||||
|
args = args[1:]
|
||||||
|
} else {
|
||||||
|
err = errors.New("No server specified")
|
||||||
|
hk.Println("Error", err)
|
||||||
|
hk.Usage()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
s, err := hk.FindServer(serverName)
|
||||||
|
if err != nil {
|
||||||
|
hk.Println("Error:", err)
|
||||||
|
hk.Usage()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
util.AddPFlagSetToPFlagSet(hk.Flags(), s.Flags())
|
||||||
|
err = s.Flags().Parse(args)
|
||||||
|
if err != nil || hk.helpFlagVal {
|
||||||
|
if err != nil {
|
||||||
|
hk.Println("Error:", err)
|
||||||
|
}
|
||||||
|
s.Usage()
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
util.InitLogs()
|
||||||
|
err = s.Run(s, s.Flags().Args())
|
||||||
|
if err != nil {
|
||||||
|
hk.Println("Error:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Usage will write out a summary for all servers that this binary supports.
|
||||||
|
func (hk *HyperKube) Usage() {
|
||||||
|
tt := `{{if .Long}}{{.Long | trim | wrap ""}}
|
||||||
|
{{end}}Usage
|
||||||
|
|
||||||
|
{{.Name}} <server> [flags]
|
||||||
|
|
||||||
|
Servers
|
||||||
|
{{range .Servers}}
|
||||||
|
{{.Name}}
|
||||||
|
{{.Long | trim | wrap " "}}{{end}}
|
||||||
|
Call '{{.Name}} <server> --help' for help on a specific server.
|
||||||
|
`
|
||||||
|
util.ExecuteTemplate(hk.Out(), tt, hk)
|
||||||
|
}
|
143
pkg/hyperkube/hyperkube_test.go
Normal file
143
pkg/hyperkube/hyperkube_test.go
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 Google Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package hyperkube
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
type result struct {
|
||||||
|
err error
|
||||||
|
output string
|
||||||
|
}
|
||||||
|
|
||||||
|
func testServer(n string) *Server {
|
||||||
|
return &Server{
|
||||||
|
SimpleUsage: n,
|
||||||
|
Long: fmt.Sprintf("A simple server named %s", n),
|
||||||
|
Run: func(s *Server, args []string) error {
|
||||||
|
s.hk.Printf("%s Run\n", s.Name())
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func testServerError(n string) *Server {
|
||||||
|
return &Server{
|
||||||
|
SimpleUsage: n,
|
||||||
|
Long: fmt.Sprintf("A simple server named %s that returns an error", n),
|
||||||
|
Run: func(s *Server, args []string) error {
|
||||||
|
s.hk.Printf("%s Run\n", s.Name())
|
||||||
|
return errors.New("Server returning error")
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func runFull(t *testing.T, args string) *result {
|
||||||
|
buf := new(bytes.Buffer)
|
||||||
|
hk := HyperKube{
|
||||||
|
Name: "hyperkube",
|
||||||
|
Long: "hyperkube is an all-in-one server binary.",
|
||||||
|
}
|
||||||
|
hk.SetOut(buf)
|
||||||
|
|
||||||
|
hk.AddServer(testServer("test1"))
|
||||||
|
hk.AddServer(testServer("test2"))
|
||||||
|
hk.AddServer(testServer("test3"))
|
||||||
|
hk.AddServer(testServerError("test-error"))
|
||||||
|
|
||||||
|
a := strings.Split(args, " ")
|
||||||
|
t.Logf("Running full with args: %q", a)
|
||||||
|
err := hk.Run(a)
|
||||||
|
|
||||||
|
r := &result{err, buf.String()}
|
||||||
|
t.Logf("Result err: %v, output: %q", r.err, r.output)
|
||||||
|
|
||||||
|
return r
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRun(t *testing.T) {
|
||||||
|
x := runFull(t, "hyperkube test1")
|
||||||
|
assert.Contains(t, x.output, "test1 Run")
|
||||||
|
assert.NoError(t, x.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLinkRun(t *testing.T) {
|
||||||
|
x := runFull(t, "test1")
|
||||||
|
assert.Contains(t, x.output, "test1 Run")
|
||||||
|
assert.NoError(t, x.err)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTopNoArgs(t *testing.T) {
|
||||||
|
x := runFull(t, "hyperkube")
|
||||||
|
assert.EqualError(t, x.err, "No server specified")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestBadServer(t *testing.T) {
|
||||||
|
x := runFull(t, "hyperkube bad-server")
|
||||||
|
assert.EqualError(t, x.err, "Server not found: bad-server")
|
||||||
|
assert.Contains(t, x.output, "Usage")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTopHelp(t *testing.T) {
|
||||||
|
x := runFull(t, "hyperkube --help")
|
||||||
|
assert.NoError(t, x.err)
|
||||||
|
assert.Contains(t, x.output, "all-in-one")
|
||||||
|
assert.Contains(t, x.output, "A simple server named test1")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTopFlags(t *testing.T) {
|
||||||
|
x := runFull(t, "hyperkube --help test1")
|
||||||
|
assert.NoError(t, x.err)
|
||||||
|
assert.Contains(t, x.output, "all-in-one")
|
||||||
|
assert.Contains(t, x.output, "A simple server named test1")
|
||||||
|
assert.NotContains(t, x.output, "test1 Run")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTopFlagsBad(t *testing.T) {
|
||||||
|
x := runFull(t, "hyperkube --bad-flag")
|
||||||
|
assert.EqualError(t, x.err, "unknown flag: --bad-flag")
|
||||||
|
assert.Contains(t, x.output, "all-in-one")
|
||||||
|
assert.Contains(t, x.output, "A simple server named test1")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerHelp(t *testing.T) {
|
||||||
|
x := runFull(t, "hyperkube test1 --help")
|
||||||
|
assert.NoError(t, x.err)
|
||||||
|
assert.Contains(t, x.output, "A simple server named test1")
|
||||||
|
assert.Contains(t, x.output, "--help=false: help for hyperkube")
|
||||||
|
assert.NotContains(t, x.output, "test1 Run")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerFlagsBad(t *testing.T) {
|
||||||
|
x := runFull(t, "hyperkube test1 --bad-flag")
|
||||||
|
assert.EqualError(t, x.err, "unknown flag: --bad-flag")
|
||||||
|
assert.Contains(t, x.output, "A simple server named test1")
|
||||||
|
assert.Contains(t, x.output, "--help=false: help for hyperkube")
|
||||||
|
assert.NotContains(t, x.output, "test1 Run")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestServerError(t *testing.T) {
|
||||||
|
x := runFull(t, "hyperkube test-error")
|
||||||
|
assert.Contains(t, x.output, "test-error Run")
|
||||||
|
assert.EqualError(t, x.err, "Server returning error")
|
||||||
|
}
|
73
pkg/hyperkube/server.go
Normal file
73
pkg/hyperkube/server.go
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2014 Google Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package hyperkube
|
||||||
|
|
||||||
|
import (
|
||||||
|
"io/ioutil"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/GoogleCloudPlatform/kubernetes/pkg/util"
|
||||||
|
|
||||||
|
"github.com/spf13/pflag"
|
||||||
|
)
|
||||||
|
|
||||||
|
type serverRunFunc func(s *Server, args []string) error
|
||||||
|
|
||||||
|
// Server describes a server that this binary can morph into.
|
||||||
|
type Server struct {
|
||||||
|
SimpleUsage string // One line description of the server.
|
||||||
|
Long string // Longer free form description of the server
|
||||||
|
Run serverRunFunc // Run the server. This is not expected to return.
|
||||||
|
|
||||||
|
flags *pflag.FlagSet // Flags for the command (and all dependents)
|
||||||
|
name string
|
||||||
|
hk *HyperKube
|
||||||
|
}
|
||||||
|
|
||||||
|
// FullUsage returns the full usage string including all of the flags.
|
||||||
|
func (s *Server) Usage() error {
|
||||||
|
tt := `{{if .Long}}{{.Long | trim | wrap ""}}
|
||||||
|
{{end}}Usage:
|
||||||
|
{{.SimpleUsage}} [flags]
|
||||||
|
|
||||||
|
Available Flags:
|
||||||
|
{{.Flags.FlagUsages}}`
|
||||||
|
|
||||||
|
return util.ExecuteTemplate(s.hk.Out(), tt, s)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Name returns the name of the command as derived from the usage line.
|
||||||
|
func (s *Server) Name() string {
|
||||||
|
if s.name != "" {
|
||||||
|
return s.name
|
||||||
|
}
|
||||||
|
name := s.SimpleUsage
|
||||||
|
i := strings.Index(name, " ")
|
||||||
|
if i >= 0 {
|
||||||
|
name = name[:i]
|
||||||
|
}
|
||||||
|
return name
|
||||||
|
}
|
||||||
|
|
||||||
|
// Flags returns a flagset for this server
|
||||||
|
func (s *Server) Flags() *pflag.FlagSet {
|
||||||
|
if s.flags == nil {
|
||||||
|
s.flags = pflag.NewFlagSet(s.Name(), pflag.ContinueOnError)
|
||||||
|
s.flags.SetOutput(ioutil.Discard)
|
||||||
|
}
|
||||||
|
return s.flags
|
||||||
|
}
|
@ -80,8 +80,10 @@ func (v *flagValueWrapper) IsBoolFlag() bool {
|
|||||||
// Imports a 'flag.Flag' into a 'pflag.FlagSet'. The "short" option is unset
|
// Imports a 'flag.Flag' into a 'pflag.FlagSet'. The "short" option is unset
|
||||||
// and the type is inferred using reflection.
|
// and the type is inferred using reflection.
|
||||||
func AddFlagToPFlagSet(f *flag.Flag, fs *pflag.FlagSet) {
|
func AddFlagToPFlagSet(f *flag.Flag, fs *pflag.FlagSet) {
|
||||||
|
if fs.Lookup(f.Name) == nil {
|
||||||
fs.Var(wrapFlagValue(f.Value), f.Name, f.Usage)
|
fs.Var(wrapFlagValue(f.Value), f.Name, f.Usage)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Adds all of the flags in a 'flag.FlagSet' package flags to a 'pflag.FlagSet'.
|
// Adds all of the flags in a 'flag.FlagSet' package flags to a 'pflag.FlagSet'.
|
||||||
func AddFlagSetToPFlagSet(fsIn *flag.FlagSet, fsOut *pflag.FlagSet) {
|
func AddFlagSetToPFlagSet(fsIn *flag.FlagSet, fsOut *pflag.FlagSet) {
|
||||||
|
48
pkg/util/template.go
Normal file
48
pkg/util/template.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 Google Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"go/doc"
|
||||||
|
"io"
|
||||||
|
"strings"
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
func wrap(indent string, s string) string {
|
||||||
|
var buf bytes.Buffer
|
||||||
|
doc.ToText(&buf, s, indent, indent+" ", 80-len(indent))
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
// ExecuteTemplate executes templateText with data and output written to w.
|
||||||
|
func ExecuteTemplate(w io.Writer, templateText string, data interface{}) error {
|
||||||
|
t := template.New("top")
|
||||||
|
t.Funcs(template.FuncMap{
|
||||||
|
"trim": strings.TrimSpace,
|
||||||
|
"wrap": wrap,
|
||||||
|
})
|
||||||
|
template.Must(t.Parse(templateText))
|
||||||
|
return t.Execute(w, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ExecuteTemplateToString(templateText string, data interface{}) (string, error) {
|
||||||
|
b := bytes.Buffer{}
|
||||||
|
err := ExecuteTemplate(&b, templateText, data)
|
||||||
|
return b.String(), err
|
||||||
|
}
|
61
pkg/util/template_test.go
Normal file
61
pkg/util/template_test.go
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2015 Google Inc. 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestWrap(t *testing.T) {
|
||||||
|
tt := `before ->{{.Long | wrap "**"}}<- after`
|
||||||
|
data := struct {
|
||||||
|
Long string
|
||||||
|
}{
|
||||||
|
`Hodor, hodor; hodor hodor;
|
||||||
|
hodor hodor... Hodor hodor hodor? Hodor. Hodor hodor hodor hodor...
|
||||||
|
Hodor hodor hodor; hodor hodor hodor! Hodor, hodor. Hodor. Hodor,
|
||||||
|
HODOR hodor, hodor hodor; hodor hodor; hodor HODOR hodor, hodor hodor?
|
||||||
|
Hodor. Hodor hodor - hodor hodor. Hodor hodor HODOR! Hodor hodor - hodor...
|
||||||
|
Hodor hodor HODOR hodor, hodor hodor hodor! Hodor, hodor... Hodor hodor
|
||||||
|
hodor hodor hodor hodor! Hodor, hodor; hodor hodor. Hodor.`,
|
||||||
|
}
|
||||||
|
output, _ := ExecuteTemplateToString(tt, data)
|
||||||
|
t.Logf("%q", output)
|
||||||
|
|
||||||
|
assert.Equal(t, `before ->**Hodor, hodor; hodor hodor; hodor hodor... Hodor hodor hodor? Hodor. Hodor
|
||||||
|
**hodor hodor hodor... Hodor hodor hodor; hodor hodor hodor! Hodor, hodor.
|
||||||
|
**Hodor. Hodor, HODOR hodor, hodor hodor; hodor hodor; hodor HODOR hodor, hodor
|
||||||
|
**hodor? Hodor. Hodor hodor - hodor hodor. Hodor hodor HODOR! Hodor hodor -
|
||||||
|
**hodor... Hodor hodor HODOR hodor, hodor hodor hodor! Hodor, hodor... Hodor
|
||||||
|
**hodor hodor hodor hodor hodor! Hodor, hodor; hodor hodor. Hodor.
|
||||||
|
<- after`, output)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestTrim(t *testing.T) {
|
||||||
|
tt := `before ->{{.Messy | trim }}<- after`
|
||||||
|
data := struct {
|
||||||
|
Messy string
|
||||||
|
}{
|
||||||
|
"\t stuff\n \r ",
|
||||||
|
}
|
||||||
|
output, _ := ExecuteTemplateToString(tt, data)
|
||||||
|
t.Logf("%q", output)
|
||||||
|
|
||||||
|
assert.Equal(t, `before ->stuff<- after`, output)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user