mirror of
				https://github.com/k3s-io/kubernetes.git
				synced 2025-11-03 23:40:03 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			99 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			99 lines
		
	
	
		
			2.2 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
// Copyright (c) 2014-2017 TSUYUSATO Kitsune
 | 
						|
// This software is released under the MIT License.
 | 
						|
// http://opensource.org/licenses/mit-license.php
 | 
						|
 | 
						|
// Package heredoc provides creation of here-documents from raw strings.
 | 
						|
//
 | 
						|
// Golang supports raw-string syntax.
 | 
						|
//     doc := `
 | 
						|
//     	Foo
 | 
						|
//     	Bar
 | 
						|
//     `
 | 
						|
// But raw-string cannot recognize indentation. Thus such content is an indented string, equivalent to
 | 
						|
//     "\n\tFoo\n\tBar\n"
 | 
						|
// I dont't want this!
 | 
						|
//
 | 
						|
// However this problem is solved by package heredoc.
 | 
						|
//     doc := heredoc.Doc(`
 | 
						|
//     	Foo
 | 
						|
//     	Bar
 | 
						|
//     `)
 | 
						|
// Is equivalent to
 | 
						|
//     "Foo\nBar\n"
 | 
						|
package heredoc
 | 
						|
 | 
						|
import (
 | 
						|
	"fmt"
 | 
						|
	"strings"
 | 
						|
	"unicode"
 | 
						|
)
 | 
						|
 | 
						|
const maxInt = int(^uint(0) >> 1)
 | 
						|
 | 
						|
// Doc returns un-indented string as here-document.
 | 
						|
func Doc(raw string) string {
 | 
						|
	skipFirstLine := false
 | 
						|
	if raw[0] == '\n' {
 | 
						|
		raw = raw[1:]
 | 
						|
	} else {
 | 
						|
		skipFirstLine = true
 | 
						|
	}
 | 
						|
 | 
						|
	lines := strings.Split(raw, "\n")
 | 
						|
 | 
						|
	minIndentSize := getMinIndent(lines, skipFirstLine)
 | 
						|
	lines = removeIndentation(lines, minIndentSize, skipFirstLine)
 | 
						|
 | 
						|
	return strings.Join(lines, "\n")
 | 
						|
}
 | 
						|
 | 
						|
// getMinIndent calculates the minimum indentation in lines, excluding empty lines.
 | 
						|
func getMinIndent(lines []string, skipFirstLine bool) int {
 | 
						|
	minIndentSize := maxInt
 | 
						|
 | 
						|
	for i, line := range lines {
 | 
						|
		if i == 0 && skipFirstLine {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		indentSize := 0
 | 
						|
		for _, r := range []rune(line) {
 | 
						|
			if unicode.IsSpace(r) {
 | 
						|
				indentSize += 1
 | 
						|
			} else {
 | 
						|
				break
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		if len(line) == indentSize {
 | 
						|
			if i == len(lines)-1 && indentSize < minIndentSize {
 | 
						|
				lines[i] = ""
 | 
						|
			}
 | 
						|
		} else if indentSize < minIndentSize {
 | 
						|
			minIndentSize = indentSize
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return minIndentSize
 | 
						|
}
 | 
						|
 | 
						|
// removeIndentation removes n characters from the front of each line in lines.
 | 
						|
// Skips first line if skipFirstLine is true, skips empty lines.
 | 
						|
func removeIndentation(lines []string, n int, skipFirstLine bool) []string {
 | 
						|
	for i, line := range lines {
 | 
						|
		if i == 0 && skipFirstLine {
 | 
						|
			continue
 | 
						|
		}
 | 
						|
 | 
						|
		if len(lines[i]) >= n {
 | 
						|
			lines[i] = line[n:]
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return lines
 | 
						|
}
 | 
						|
 | 
						|
// Docf returns unindented and formatted string as here-document.
 | 
						|
// Formatting is done as for fmt.Printf().
 | 
						|
func Docf(raw string, args ...interface{}) string {
 | 
						|
	return fmt.Sprintf(Doc(raw), args...)
 | 
						|
}
 |