github.com/jaylevin/jenkins-library@v1.230.4/pkg/maven/model.go (about)

     1  package maven
     2  
     3  import (
     4  	"encoding/xml"
     5  	"fmt"
     6  	"github.com/SAP/jenkins-library/pkg/piperutils"
     7  	"path/filepath"
     8  )
     9  
    10  // Project describes the Maven object model.
    11  type Project struct {
    12  	XMLName      xml.Name     `xml:"project"`
    13  	Parent       Parent       `xml:"parent"`
    14  	GroupID      string       `xml:"groupId"`
    15  	ArtifactID   string       `xml:"artifactId"`
    16  	Version      string       `xml:"version"`
    17  	Packaging    string       `xml:"packaging"`
    18  	Name         string       `xml:"name"`
    19  	Dependencies []Dependency `xml:"dependencies>dependency"`
    20  	Modules      []string     `xml:"modules>module"`
    21  }
    22  
    23  // Parent describes the coordinates a module's parent POM.
    24  type Parent struct {
    25  	XMLName    xml.Name `xml:"parent"`
    26  	GroupID    string   `xml:"groupId"`
    27  	ArtifactID string   `xml:"artifactId"`
    28  	Version    string   `xml:"version"`
    29  }
    30  
    31  // Dependency describes a dependency of the module.
    32  type Dependency struct {
    33  	XMLName    xml.Name    `xml:"dependency"`
    34  	GroupID    string      `xml:"groupId"`
    35  	ArtifactID string      `xml:"artifactId"`
    36  	Version    string      `xml:"version"`
    37  	Classifier string      `xml:"classifier"`
    38  	Type       string      `xml:"type"`
    39  	Scope      string      `xml:"scope"`
    40  	Exclusions []Exclusion `xml:"exclusions>exclusion"`
    41  }
    42  
    43  // Exclusion describes an exclusion within a dependency.
    44  type Exclusion struct {
    45  	XMLName    xml.Name `xml:"exclusion"`
    46  	GroupID    string   `xml:"groupId"`
    47  	ArtifactID string   `xml:"artifactId"`
    48  }
    49  
    50  // ParsePOM parses the provided XML raw data into a Project.
    51  func ParsePOM(xmlData []byte) (*Project, error) {
    52  	project := Project{}
    53  	err := xml.Unmarshal(xmlData, &project)
    54  	if err != nil {
    55  		return nil, fmt.Errorf("failed to parse POM data: %w", err)
    56  	}
    57  	return &project, nil
    58  }
    59  
    60  // ModuleInfo describes a location and Project of a maven module.
    61  type ModuleInfo struct {
    62  	PomXMLPath string
    63  	Project    *Project
    64  }
    65  
    66  type visitUtils interface {
    67  	FileExists(path string) (bool, error)
    68  	FileRead(path string) ([]byte, error)
    69  }
    70  
    71  // VisitAllMavenModules ...
    72  func VisitAllMavenModules(path string, utils visitUtils, excludes []string, callback func(info ModuleInfo) error) error {
    73  	pomXMLPath := filepath.Join(path, "pom.xml")
    74  	if piperutils.ContainsString(excludes, pomXMLPath) {
    75  		return nil
    76  	}
    77  
    78  	exists, _ := utils.FileExists(pomXMLPath)
    79  	if !exists {
    80  		return nil
    81  	}
    82  
    83  	pomXMLContents, err := utils.FileRead(pomXMLPath)
    84  	if err != nil {
    85  		return fmt.Errorf("failed to read file contents of '%s': %w", pomXMLPath, err)
    86  	}
    87  
    88  	project, err := ParsePOM(pomXMLContents)
    89  	if err != nil {
    90  		return fmt.Errorf("failed to parse file contents of '%s': %w", pomXMLPath, err)
    91  	}
    92  
    93  	err = callback(ModuleInfo{PomXMLPath: pomXMLPath, Project: project})
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	if len(project.Modules) == 0 {
    99  		return nil
   100  	}
   101  
   102  	for _, module := range project.Modules {
   103  		subPomPath := filepath.Join(path, module)
   104  		err = VisitAllMavenModules(subPomPath, utils, excludes, callback)
   105  		if err != nil {
   106  			return err
   107  		}
   108  	}
   109  	return nil
   110  }