github.com/jaylevin/jenkins-library@v1.230.4/pkg/cnbutils/project/descriptor.go (about)

     1  // Package project handles project.toml parsing
     2  package project
     3  
     4  import (
     5  	"errors"
     6  
     7  	"github.com/SAP/jenkins-library/pkg/cnbutils"
     8  	"github.com/SAP/jenkins-library/pkg/cnbutils/registry"
     9  	piperhttp "github.com/SAP/jenkins-library/pkg/http"
    10  	"github.com/SAP/jenkins-library/pkg/log"
    11  	"github.com/pelletier/go-toml"
    12  	ignore "github.com/sabhiram/go-gitignore"
    13  )
    14  
    15  type script struct {
    16  	API    string `toml:"api"`
    17  	Inline string `toml:"inline"`
    18  	Shell  string `toml:"shell"`
    19  }
    20  type buildpack struct {
    21  	ID      string `toml:"id"`
    22  	Version string `toml:"version"`
    23  	URI     string `toml:"uri"`
    24  	Script  script `toml:"script"`
    25  }
    26  
    27  type envVar struct {
    28  	Name  string `toml:"name"`
    29  	Value string `toml:"value"`
    30  }
    31  
    32  type build struct {
    33  	Include    []string    `toml:"include"`
    34  	Exclude    []string    `toml:"exclude"`
    35  	Buildpacks []buildpack `toml:"buildpacks"`
    36  	Env        []envVar    `toml:"env"`
    37  }
    38  
    39  type project struct {
    40  	ID string `toml:"id"`
    41  }
    42  
    43  type projectDescriptor struct {
    44  	Build    build                  `toml:"build"`
    45  	Project  project                `toml:"project"`
    46  	Metadata map[string]interface{} `toml:"metadata"`
    47  }
    48  
    49  type Descriptor struct {
    50  	Exclude    *ignore.GitIgnore
    51  	Include    *ignore.GitIgnore
    52  	EnvVars    map[string]interface{}
    53  	Buildpacks []string
    54  	ProjectID  string
    55  }
    56  
    57  func ParseDescriptor(descriptorPath string, utils cnbutils.BuildUtils, httpClient piperhttp.Sender) (*Descriptor, error) {
    58  	descriptor := &Descriptor{}
    59  
    60  	descriptorContent, err := utils.FileRead(descriptorPath)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  
    65  	rawDescriptor := projectDescriptor{}
    66  	err = toml.Unmarshal(descriptorContent, &rawDescriptor)
    67  	if err != nil {
    68  		return nil, err
    69  	}
    70  
    71  	if rawDescriptor.Build.Buildpacks != nil && len(rawDescriptor.Build.Buildpacks) > 0 {
    72  		buildpacksImg, err := rawDescriptor.Build.searchBuildpacks(httpClient)
    73  		if err != nil {
    74  			return nil, err
    75  		}
    76  
    77  		descriptor.Buildpacks = buildpacksImg
    78  	}
    79  
    80  	if rawDescriptor.Build.Env != nil && len(rawDescriptor.Build.Env) > 0 {
    81  		descriptor.EnvVars = rawDescriptor.Build.envToMap()
    82  	}
    83  
    84  	if len(rawDescriptor.Build.Exclude) > 0 && len(rawDescriptor.Build.Include) > 0 {
    85  		return nil, errors.New("project descriptor options 'exclude' and 'include' are mutually exclusive")
    86  	}
    87  
    88  	if len(rawDescriptor.Build.Exclude) > 0 {
    89  		descriptor.Exclude = ignore.CompileIgnoreLines(rawDescriptor.Build.Exclude...)
    90  	}
    91  
    92  	if len(rawDescriptor.Build.Include) > 0 {
    93  		descriptor.Include = ignore.CompileIgnoreLines(rawDescriptor.Build.Include...)
    94  	}
    95  
    96  	if len(rawDescriptor.Project.ID) > 0 {
    97  		descriptor.ProjectID = rawDescriptor.Project.ID
    98  	}
    99  
   100  	return descriptor, nil
   101  }
   102  
   103  func (b *build) envToMap() map[string]interface{} {
   104  	envMap := map[string]interface{}{}
   105  
   106  	for _, e := range b.Env {
   107  		if len(e.Name) == 0 || len(e.Value) == 0 {
   108  			continue
   109  		}
   110  
   111  		envMap[e.Name] = e.Value
   112  	}
   113  
   114  	return envMap
   115  }
   116  
   117  func (b *build) searchBuildpacks(httpClient piperhttp.Sender) ([]string, error) {
   118  	var bpackImg []string
   119  
   120  	for _, bpack := range b.Buildpacks {
   121  		if bpack.Script != (script{}) {
   122  			return nil, errors.New("inline buildpacks are not supported")
   123  		}
   124  
   125  		if bpack.URI != "" {
   126  			log.Entry().Debugf("Adding buildpack using URI: %s", bpack.URI)
   127  			bpackImg = append(bpackImg, bpack.URI)
   128  		} else if bpack.ID != "" {
   129  			imgURL, err := registry.SearchBuildpack(bpack.ID, bpack.Version, httpClient, "")
   130  			if err != nil {
   131  				return nil, err
   132  			}
   133  
   134  			bpackImg = append(bpackImg, imgURL)
   135  		} else {
   136  			return nil, errors.New("invalid buildpack entry in project.toml, either URI or ID should be specified")
   137  		}
   138  
   139  	}
   140  
   141  	return bpackImg, nil
   142  }