github.com/drone/go-convert@v0.0.0-20240307072510-6bd371c65e61/convert/harness/downgrader/util.go (about)

     1  // Copyright 2022 Harness, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package downgrader
    16  
    17  import (
    18  	"strings"
    19  	"unicode"
    20  
    21  	"golang.org/x/text/unicode/norm"
    22  )
    23  
    24  // this function attempts to convert a freeform name to a
    25  // harness name.
    26  //
    27  // ^[a-zA-Z_][-0-9a-zA-Z_\s]{0,127}$
    28  func convertName(s string) string {
    29  	s = strings.TrimSpace(s)
    30  	s = norm.NFKD.String(s)
    31  	s = strings.Map(safe, s)
    32  	if len(s) > 0 {
    33  		f := string(s[0]) // first letter of the string
    34  		return strings.Map(safeFirstLetter, f) + s[1:]
    35  	}
    36  	if len(s) > 127 {
    37  		return s[:127] // trim if > 127 characters
    38  	}
    39  	return s
    40  }
    41  
    42  // helper function maps restricted runes to allowed runes
    43  // for the name.
    44  func safe(r rune) rune {
    45  	switch {
    46  	case unicode.IsSpace(r):
    47  		return ' '
    48  	case unicode.IsNumber(r):
    49  		return r
    50  	case unicode.IsLetter(r):
    51  		return r
    52  	}
    53  	switch r {
    54  	case '_', '-':
    55  		return r
    56  	}
    57  	return -1
    58  }
    59  
    60  // helper function maps restricted runes to allowed runes
    61  // for the first letter of the name.
    62  func safeFirstLetter(r rune) rune {
    63  	switch {
    64  	case unicode.IsNumber(r):
    65  		return r
    66  	case unicode.IsLetter(r):
    67  		return r
    68  	}
    69  	switch r {
    70  	case '_':
    71  		return r
    72  	}
    73  	return -1
    74  }