github.com/drone/go-convert@v0.0.0-20240307072510-6bd371c65e61/convert/gitlab/yaml/pipeline.go (about)

     1  // Copyright 2022 Harness, Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package yaml
    16  
    17  import (
    18  	"strings"
    19  )
    20  
    21  type (
    22  	// Pipeline defines a gitlab pipeline.
    23  	Pipeline struct {
    24  		Artifacts    *Artifacts `yaml:"artifacts,omitempty"`
    25  		Schema       string
    26  		Default      *Default
    27  		Include      []*Include
    28  		Image        *Image
    29  		Services     []*Image
    30  		BeforeScript []string
    31  		AfterScript  []string
    32  		Variables    map[string]*Variable
    33  		Cache        *Cache
    34  		Stages       []string
    35  		Pages        *Job
    36  		Workflow     *Workflow
    37  		Jobs         map[string]*Job
    38  		TemplateJobs map[string]*Job `yaml:"-"`
    39  	}
    40  
    41  	// pipeline is a temporary structure to parse the pipeline.
    42  	pipeline struct {
    43  		Artifacts    *Artifacts           `yaml:"artifacts,omitempty"`
    44  		Schema       string               `yaml:"$schema,omitempty"`
    45  		Default      *Default             `yaml:"default,omitempty"`
    46  		Include      []*Include           `yaml:"include,omitempty"`
    47  		Image        *Image               `yaml:"image,omitempty"`
    48  		Services     []*Image             `yaml:"services,omitempty"`
    49  		BeforeScript []string             `yaml:"before_script,omitempty"`
    50  		AfterScript  []string             `yaml:"after_script,omitempty"`
    51  		Variables    map[string]*Variable `yaml:"variables,omitempty"`
    52  		Cache        *Cache               `yaml:"cache,omitempty"`
    53  		Stages       []string             `yaml:"stages,omitempty"`
    54  		Pages        *Job                 `yaml:"pages,omitempty"`
    55  		Workflow     *Workflow            `yaml:"workflow,omitempty"`
    56  		Jobs         map[string]*Job      `yaml:",inline"`
    57  	}
    58  
    59  	// Default defines global pipeline defaults.
    60  	Default struct {
    61  		After         []string   `yaml:"after_script,omitempty"`
    62  		Before        []string   `yaml:"before_script,omitempty"`
    63  		Artifacts     *Artifacts `yaml:"artifacts,omitempty"`
    64  		Cache         *Cache     `yaml:"cache,omitempty"`
    65  		Image         *Image     `yaml:"image,omitempty"`
    66  		Interruptible bool       `yaml:"interruptible,omitempty"`
    67  		Retry         *Retry     `yaml:"retry,omitempty"`
    68  		Services      []*Image   `yaml:"services,omitempty"`
    69  		Tags          []string   `yaml:"tags,omitempty"`
    70  		Timeout       string     `yaml:"duration,omitempty"`
    71  	}
    72  )
    73  
    74  func (p *Pipeline) UnmarshalYAML(unmarshal func(interface{}) error) error {
    75  	out := new(pipeline)
    76  	if err := unmarshal(&out); err != nil {
    77  		return err
    78  	}
    79  	p.Artifacts = out.Artifacts
    80  	p.Schema = out.Schema
    81  	p.Default = out.Default
    82  	p.Include = out.Include
    83  	p.Image = out.Image
    84  	p.Services = out.Services
    85  	p.BeforeScript = out.BeforeScript
    86  	p.AfterScript = out.AfterScript
    87  	p.Variables = out.Variables
    88  	p.Cache = out.Cache
    89  	p.Stages = out.Stages
    90  	p.Pages = out.Pages
    91  	p.Workflow = out.Workflow
    92  	p.Jobs = out.Jobs
    93  	hasTemplateJobs := false
    94  
    95  	for k := range out.Jobs {
    96  		if strings.HasPrefix(k, ".") {
    97  			hasTemplateJobs = true
    98  			break
    99  		}
   100  	}
   101  
   102  	if hasTemplateJobs {
   103  		p.TemplateJobs = make(map[string]*Job) // Initialize as an empty map only if there are template jobs
   104  
   105  		for k, v := range out.Jobs {
   106  			if strings.HasPrefix(k, ".") {
   107  				delete(p.Jobs, k)
   108  				p.TemplateJobs[k] = v
   109  			}
   110  		}
   111  	}
   112  	return nil
   113  }
   114  
   115  // MarshalYAML implements yaml marshalling.
   116  func (p *Pipeline) MarshalYAML() (interface{}, error) {
   117  	out := new(pipeline)
   118  	out.Artifacts = p.Artifacts
   119  	out.Schema = p.Schema
   120  	out.Default = p.Default
   121  	out.Include = p.Include
   122  	out.Image = p.Image
   123  	out.Services = p.Services
   124  	out.BeforeScript = p.BeforeScript
   125  	out.AfterScript = p.AfterScript
   126  	out.Variables = p.Variables
   127  	out.Cache = p.Cache
   128  	out.Stages = p.Stages
   129  	out.Pages = p.Pages
   130  	out.Workflow = p.Workflow
   131  	out.Jobs = p.Jobs
   132  
   133  	for k, v := range p.TemplateJobs {
   134  		out.Jobs[k] = v
   135  	}
   136  	return out, nil
   137  }