79 lines
2.4 KiB
Go
79 lines
2.4 KiB
Go
|
/*
|
||
|
Copyright 2019 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 crd
|
||
|
|
||
|
import (
|
||
|
"strings"
|
||
|
"unicode"
|
||
|
|
||
|
apiext "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
|
||
|
)
|
||
|
|
||
|
// TruncateDescription truncates the description of fields in given schema if it
|
||
|
// exceeds maxLen.
|
||
|
// It tries to chop off the description at the closest sentence boundary.
|
||
|
func TruncateDescription(schema *apiext.JSONSchemaProps, maxLen int) {
|
||
|
EditSchema(schema, descVisitor{maxLen: maxLen})
|
||
|
}
|
||
|
|
||
|
// descVisitor recursively visits all fields in the schema and truncates the
|
||
|
// description of the fields to specified maxLen.
|
||
|
type descVisitor struct {
|
||
|
// maxLen is the maximum allowed length for decription of a field
|
||
|
maxLen int
|
||
|
}
|
||
|
|
||
|
func (v descVisitor) Visit(schema *apiext.JSONSchemaProps) SchemaVisitor {
|
||
|
if schema == nil {
|
||
|
return v
|
||
|
}
|
||
|
if v.maxLen < 0 {
|
||
|
return nil /* no further work to be done for this schema */
|
||
|
}
|
||
|
if v.maxLen == 0 {
|
||
|
schema.Description = ""
|
||
|
return v
|
||
|
}
|
||
|
if len(schema.Description) > v.maxLen {
|
||
|
schema.Description = truncateString(schema.Description, v.maxLen)
|
||
|
return v
|
||
|
}
|
||
|
return v
|
||
|
}
|
||
|
|
||
|
// truncateString truncates given desc string if it exceeds maxLen. It may
|
||
|
// return string with length less than maxLen even in cases where original desc
|
||
|
// exceeds maxLen because it tries to chop off the desc at the closest sentence
|
||
|
// boundary to avoid incomplete sentences.
|
||
|
func truncateString(desc string, maxLen int) string {
|
||
|
desc = desc[0:maxLen]
|
||
|
|
||
|
// Trying to chop off at closest sentence boundary.
|
||
|
if n := strings.LastIndexFunc(desc, isSentenceTerminal); n > 0 {
|
||
|
return desc[0 : n+1]
|
||
|
}
|
||
|
// TODO(droot): Improve the logic to chop off at closest word boundary
|
||
|
// or add elipses (...) to indicate that it's chopped incase no closest
|
||
|
// sentence found within maxLen.
|
||
|
return desc
|
||
|
}
|
||
|
|
||
|
// helper function to determine if given rune is a sentence terminal or not.
|
||
|
func isSentenceTerminal(r rune) bool {
|
||
|
return unicode.Is(unicode.STerm, r)
|
||
|
}
|