github.com/jfrog/jfrog-cli-core/v2@v2.51.0/artifactory/commands/transferconfig/configxmlutils/xmlutils.go (about) 1 package configxmlutils 2 3 import ( 4 "fmt" 5 "regexp" 6 7 "github.com/jfrog/jfrog-cli-core/v2/artifactory/utils" 8 "github.com/jfrog/jfrog-client-go/utils/errorutils" 9 "github.com/jfrog/jfrog-client-go/utils/log" 10 ) 11 12 // Remove all repositories from the config XML. 13 // Since Artifactory 7.49, we transfer the repositories using GET and POST to /api/repository. 14 // Therefore we don't need to have then in the config.xml. 15 func RemoveAllRepositories(configXml string) (string, error) { 16 for _, repoType := range append(utils.RepoTypes, "releaseBundles") { 17 xmlTagIndices, exist, err := findAllXmlTagIndices(configXml, repoType+`Repositories`, true) 18 if err != nil { 19 return "", err 20 } 21 if !exist { 22 continue 23 } 24 prefix, _, suffix := splitXmlTag(configXml, xmlTagIndices, 0) 25 configXml = prefix + suffix 26 } 27 return configXml, nil 28 } 29 30 // Find all indiced of the input tagName in the XML. 31 // xmlContent - XML content 32 // tagName - Tag name in XML 33 // ensureSingle - Make this function returns an error if more than 1 appearance of the tag detected 34 // Return values: 35 // indices - The 'i' represents appearance of a single tag and the 'j' represents the 4 indices of the start and end positions of the tag. 36 // exist - True if the tag exist in the XML 37 // err - Not nil if ensureSingle=true and there are many positions of the tag, or in case of an unexpected error 38 func findAllXmlTagIndices(xmlContent, tagName string, ensureSingle bool) (indices [][]int, exist bool, err error) { 39 tagPattern, err := regexp.Compile(fmt.Sprintf(`<%s>([\s\S]*?)</%s>`, tagName, tagName)) 40 if err != nil { 41 return 42 } 43 indices = tagPattern.FindAllStringSubmatchIndex(xmlContent, -1) 44 if ensureSingle { 45 if err = ensureSingleTag(tagName, indices); err != nil { 46 return 47 } 48 } 49 50 return indices, len(indices) > 0, nil 51 } 52 53 // Split the content into prefix, inner and suffix according to the output of findAllXmlTagIndices. 54 // xmlContent - The XML content 55 // indices - Indices of a tag in the XML (output of findAllXmlTagIndices) 56 // currentIndex - The current index of the tag 57 func splitXmlTag(xmlContent string, indices [][]int, currentIndex int) (prefix, inner, suffix string) { 58 if currentIndex == 0 { 59 prefix = xmlContent[:indices[0][2]] 60 } else { 61 prefix = xmlContent[indices[currentIndex][0]:indices[currentIndex][2]] 62 } 63 if currentIndex < len(indices)-1 { 64 suffix = xmlContent[indices[currentIndex][3]:indices[currentIndex+1][0]] 65 } else { 66 suffix = xmlContent[indices[currentIndex][3]:] 67 } 68 return prefix, xmlContent[indices[currentIndex][2]:indices[currentIndex][3]], suffix 69 } 70 71 // Return error if the number of appearances of the tag in an XML is > 1. 72 func ensureSingleTag(tagName string, xmlTagIndices [][]int) error { 73 if len(xmlTagIndices) == 0 { 74 log.Debug("No <" + tagName + "> were found in source artifactory.config.xml.") 75 // The tag was not found in the XML 76 return nil 77 } 78 if len(xmlTagIndices) > 1 { 79 return errorutils.CheckErrorf("Found multiple <%s> entities in source artifactory.config.xml", tagName) 80 } 81 return nil 82 }