...

Source file src/k8s.io/kubernetes/cmd/gotemplate/gotemplate.go

Documentation: k8s.io/kubernetes/cmd/gotemplate

     1  /*
     2  Copyright 2023 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package main
    18  
    19  import (
    20  	"bytes"
    21  	"fmt"
    22  	"io"
    23  	"os"
    24  	"strings"
    25  	"text/template"
    26  )
    27  
    28  // gotemplate is a simple CLI for text/template. It reads from stdin and writes to stdout.
    29  // Optional arguments are <key>=<value> pairs which can be used as {{.<key>}} to inject
    30  // the <value> for that key.
    31  //
    32  // Besides the default functions (https://pkg.go.dev/text/template#hdr-Functions),
    33  // gotemplate also implements:
    34  // - include <filename>: returns the content of that file as string
    35  // - indent <number of spaces> <string>: replace each newline with "newline + spaces", indent the newline at the end
    36  // - trim <string>: strip leading and trailing whitespace
    37  
    38  func main() {
    39  	kvs := make(map[string]string)
    40  
    41  	for _, keyValue := range os.Args[1:] {
    42  		index := strings.Index(keyValue, "=")
    43  		if index <= 0 {
    44  			fmt.Fprintf(os.Stderr, "optional arguments must be of the form <key>=<value>, got instead: %q\n", keyValue)
    45  			os.Exit(1)
    46  		}
    47  		kvs[keyValue[0:index]] = keyValue[index+1:]
    48  	}
    49  
    50  	if err := generate(os.Stdin, os.Stdout, kvs); err != nil {
    51  		fmt.Fprintf(os.Stderr, "Error: %v\n", err)
    52  		os.Exit(1)
    53  	}
    54  }
    55  
    56  func generate(in io.Reader, out io.Writer, data interface{}) error {
    57  	var buf bytes.Buffer
    58  	if _, err := buf.ReadFrom(in); err != nil {
    59  		return fmt.Errorf("reading input: %v", err)
    60  	}
    61  
    62  	funcMap := template.FuncMap{
    63  		"include": include,
    64  		"indent":  indent,
    65  		"trim":    trim,
    66  	}
    67  
    68  	tmpl, err := template.New("").Funcs(funcMap).Parse(buf.String())
    69  	if err != nil {
    70  		return fmt.Errorf("parsing input as text template: %v", err)
    71  	}
    72  
    73  	if err := tmpl.Execute(out, data); err != nil {
    74  		return fmt.Errorf("generating result: %v", err)
    75  	}
    76  	return nil
    77  }
    78  
    79  func include(filename string) (string, error) {
    80  	content, err := os.ReadFile(filename)
    81  	if err != nil {
    82  		return "", err
    83  	}
    84  	return string(content), nil
    85  }
    86  
    87  func indent(numSpaces int, content string) string {
    88  	if content == "" {
    89  		return ""
    90  	}
    91  	prefix := strings.Repeat(" ", numSpaces)
    92  	return strings.ReplaceAll(content, "\n", "\n"+prefix)
    93  }
    94  
    95  func trim(content string) string {
    96  	return strings.TrimSpace(content)
    97  }
    98  

View as plain text