2021-09-19 12:00:00 +00:00
|
|
|
// Copyright (c) 2019, Drone IO Inc.
|
|
|
|
// Copyright (c) 2021, Robert Kaussow <mail@thegeeklab.de>
|
2019-02-10 19:00:16 +00:00
|
|
|
|
2019-01-22 23:44:17 +00:00
|
|
|
package linter
|
|
|
|
|
|
|
|
import (
|
|
|
|
"errors"
|
|
|
|
|
|
|
|
"github.com/drone/drone-yaml/yaml"
|
|
|
|
)
|
|
|
|
|
|
|
|
// ErrDuplicatePipelineName is returned when two Pipeline
|
|
|
|
// resources have the same name.
|
|
|
|
var ErrDuplicatePipelineName = errors.New("linter: duplicate pipeline names")
|
|
|
|
|
|
|
|
// ErrMissingPipelineDependency is returned when a Pipeline
|
2022-04-25 10:56:05 +00:00
|
|
|
// defines dependencies that are invalid or unknown.
|
2019-01-22 23:44:17 +00:00
|
|
|
var ErrMissingPipelineDependency = errors.New("linter: invalid or unknown pipeline dependency")
|
|
|
|
|
|
|
|
// ErrCyclicalPipelineDependency is returned when a Pipeline
|
|
|
|
// defines a cyclical dependency, which would result in an
|
|
|
|
// infinite execution loop.
|
|
|
|
var ErrCyclicalPipelineDependency = errors.New("linter: cyclical pipeline dependency detected")
|
|
|
|
|
|
|
|
// ErrPipelineSelfDependency is returned when a Pipeline
|
|
|
|
// defines a dependency on itself.
|
|
|
|
var ErrPipelineSelfDependency = errors.New("linter: pipeline cannot have a dependency on itself")
|
|
|
|
|
|
|
|
// Manifest performs lint operations for a manifest.
|
2023-03-20 08:38:05 +00:00
|
|
|
func Manifest(manifest *yaml.Manifest) error {
|
2023-02-08 09:14:20 +00:00
|
|
|
return checkPipelines(manifest)
|
2019-01-22 23:44:17 +00:00
|
|
|
}
|
|
|
|
|
2023-02-08 09:14:20 +00:00
|
|
|
func checkPipelines(manifest *yaml.Manifest) error {
|
2019-01-22 23:44:17 +00:00
|
|
|
names := map[string]struct{}{}
|
2023-02-08 09:14:20 +00:00
|
|
|
|
2019-01-22 23:44:17 +00:00
|
|
|
for _, resource := range manifest.Resources {
|
|
|
|
switch v := resource.(type) {
|
|
|
|
case *yaml.Pipeline:
|
|
|
|
_, ok := names[v.Name]
|
|
|
|
if ok {
|
|
|
|
return ErrDuplicatePipelineName
|
|
|
|
}
|
2023-02-08 09:14:20 +00:00
|
|
|
|
2019-01-22 23:44:17 +00:00
|
|
|
names[v.Name] = struct{}{}
|
2023-02-08 09:14:20 +00:00
|
|
|
|
2019-01-22 23:44:17 +00:00
|
|
|
err := checkPipelineDeps(v, names)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2023-02-08 09:14:20 +00:00
|
|
|
|
2019-07-29 07:23:35 +00:00
|
|
|
if (v.Kind == "pipeline" || v.Kind == "") && (v.Type == "" || v.Type == "docker") {
|
2019-09-02 15:58:51 +00:00
|
|
|
err = checkPlatform(v.Platform)
|
2019-05-20 18:26:46 +00:00
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
2019-01-22 23:44:17 +00:00
|
|
|
}
|
2022-04-25 10:56:05 +00:00
|
|
|
default:
|
|
|
|
continue
|
2019-01-22 23:44:17 +00:00
|
|
|
}
|
|
|
|
}
|
2023-02-08 09:14:20 +00:00
|
|
|
|
2019-01-22 23:44:17 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkPipelineDeps(pipeline *yaml.Pipeline, deps map[string]struct{}) error {
|
|
|
|
for _, dep := range pipeline.DependsOn {
|
|
|
|
_, ok := deps[dep]
|
|
|
|
if !ok {
|
|
|
|
return ErrMissingPipelineDependency
|
|
|
|
}
|
2023-02-08 09:14:20 +00:00
|
|
|
|
2019-01-22 23:44:17 +00:00
|
|
|
if pipeline.Name == dep {
|
|
|
|
return ErrPipelineSelfDependency
|
|
|
|
}
|
|
|
|
}
|
2023-02-08 09:14:20 +00:00
|
|
|
|
2019-01-22 23:44:17 +00:00
|
|
|
return nil
|
|
|
|
}
|