github.com/SAP/jenkins-library@v1.362.0/pkg/versioning/gomodfile.go (about)

     1  package versioning
     2  
     3  import (
     4  	"os"
     5  	"strings"
     6  
     7  	"golang.org/x/mod/modfile"
     8  
     9  	"github.com/pkg/errors"
    10  )
    11  
    12  // GoMod utility to interact with Go Modules specific versioning
    13  type GoMod struct {
    14  	path                   string
    15  	readFile               func(string) ([]byte, error)
    16  	writeFile              func(string, []byte, os.FileMode) error
    17  	fileExists             func(string) (bool, error)
    18  	buildDescriptorContent string
    19  }
    20  
    21  func (m *GoMod) init() error {
    22  	if m.readFile == nil {
    23  		m.readFile = os.ReadFile
    24  	}
    25  	if m.writeFile == nil {
    26  		m.writeFile = os.WriteFile
    27  	}
    28  	if len(m.buildDescriptorContent) == 0 {
    29  		content, err := m.readFile(m.path)
    30  		if err != nil {
    31  			return errors.Wrapf(err, "failed to read file '%v'", m.path)
    32  		}
    33  		m.buildDescriptorContent = string(content)
    34  	}
    35  	return nil
    36  }
    37  
    38  // GetVersion returns the go.mod descriptor version property
    39  func (m *GoMod) GetVersion() (string, error) {
    40  	buildDescriptorFilePath := m.path
    41  	var err error
    42  	if strings.Contains(m.path, "go.mod") {
    43  		buildDescriptorFilePath, err = searchDescriptor([]string{"version.txt", "VERSION"}, m.fileExists)
    44  		if err != nil {
    45  			err = m.init()
    46  			if err != nil {
    47  				return "", errors.Wrapf(err, "failed to read file '%v'", m.path)
    48  			}
    49  
    50  			parsed, err := modfile.Parse(m.path, []byte(m.buildDescriptorContent), nil)
    51  			if err != nil {
    52  				return "", errors.Wrap(err, "failed to parse go.mod file")
    53  			}
    54  			if parsed.Module.Mod.Version != "" {
    55  				return parsed.Module.Mod.Version, nil
    56  			}
    57  
    58  			return "", errors.Wrap(err, "failed to retrieve version")
    59  		}
    60  	}
    61  	artifact := &Versionfile{
    62  		path:             buildDescriptorFilePath,
    63  		versioningScheme: m.VersioningScheme(),
    64  	}
    65  	return artifact.GetVersion()
    66  }
    67  
    68  // SetVersion sets the go.mod descriptor version property
    69  func (m *GoMod) SetVersion(v string) error {
    70  	return nil
    71  }
    72  
    73  // VersioningScheme returns the relevant versioning scheme
    74  func (m *GoMod) VersioningScheme() string {
    75  	return "semver2"
    76  }
    77  
    78  // GetCoordinates returns the go.mod build descriptor coordinates
    79  func (m *GoMod) GetCoordinates() (Coordinates, error) {
    80  	result := Coordinates{}
    81  	err := m.init()
    82  	if err != nil {
    83  		return result, err
    84  	}
    85  
    86  	parsed, err := modfile.Parse(m.path, []byte(m.buildDescriptorContent), nil)
    87  	if err != nil {
    88  		return result, errors.Wrap(err, "failed to parse go.mod file")
    89  	}
    90  
    91  	if parsed.Module == nil {
    92  		return result, errors.Wrap(err, "failed to parse go.mod file")
    93  	}
    94  	if parsed.Module.Mod.Path != "" {
    95  		artifactSplit := strings.Split(parsed.Module.Mod.Path, "/")
    96  		artifactID := artifactSplit[len(artifactSplit)-1]
    97  		result.ArtifactID = artifactID
    98  
    99  		goModPath := parsed.Module.Mod.Path
   100  		lastIndex := strings.LastIndex(goModPath, "/")
   101  		groupID := goModPath[0:lastIndex]
   102  		result.GroupID = groupID
   103  	}
   104  	result.Version = parsed.Module.Mod.Version
   105  	if result.Version == "" {
   106  		result.Version = "unspecified"
   107  	}
   108  	return result, nil
   109  }