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  }