github.com/grahambrereton-form3/tilt@v0.10.18/internal/testutils/manifestbuilder/manifestbuilder.go (about)

     1  package manifestbuilder
     2  
     3  import (
     4  	"testing"
     5  
     6  	"k8s.io/apimachinery/pkg/labels"
     7  
     8  	"github.com/windmilleng/tilt/pkg/model"
     9  )
    10  
    11  // Builds Manifest objects for testing.
    12  //
    13  // To create well-formed manifests, we want to make sure that:
    14  // - The relationships between targets are internally consistent
    15  //   (e.g., if there's an ImageTarget and a K8sTarget in the manifest, then
    16  //    the K8sTarget should depend on the ImageTarget).
    17  // - Any filepaths in the manifest are scoped to the
    18  //   test directory (e.g., we're not trying to watch random directories
    19  //   outside the test environment).
    20  
    21  type ManifestBuilder struct {
    22  	f    Fixture
    23  	name model.ManifestName
    24  
    25  	k8sYAML         string
    26  	k8sPodSelectors []labels.Selector
    27  	dcConfigPaths   []string
    28  	localCmd        string
    29  	localDeps       []string
    30  	resourceDeps    []string
    31  
    32  	iTargets []model.ImageTarget
    33  }
    34  
    35  func New(f Fixture, name model.ManifestName) ManifestBuilder {
    36  	return ManifestBuilder{
    37  		f:    f,
    38  		name: name,
    39  	}
    40  }
    41  
    42  func (b ManifestBuilder) WithK8sYAML(yaml string) ManifestBuilder {
    43  	b.k8sYAML = yaml
    44  	return b
    45  }
    46  
    47  func (b ManifestBuilder) WithK8sPodSelectors(podSelectors []labels.Selector) ManifestBuilder {
    48  	b.k8sPodSelectors = podSelectors
    49  	return b
    50  }
    51  
    52  func (b ManifestBuilder) WithDockerCompose() ManifestBuilder {
    53  	b.dcConfigPaths = []string{b.f.JoinPath("docker-compose.yml")}
    54  	return b
    55  }
    56  
    57  func (b ManifestBuilder) WithLocalResource(cmd string, deps []string) ManifestBuilder {
    58  	b.localCmd = cmd
    59  	b.localDeps = deps
    60  	return b
    61  }
    62  
    63  func (b ManifestBuilder) WithImageTarget(iTarg model.ImageTarget) ManifestBuilder {
    64  	b.iTargets = append(b.iTargets, iTarg)
    65  	return b
    66  }
    67  
    68  func (b ManifestBuilder) WithImageTargets(iTargs ...model.ImageTarget) ManifestBuilder {
    69  	b.iTargets = append(b.iTargets, iTargs...)
    70  	return b
    71  }
    72  
    73  func (b ManifestBuilder) WithLiveUpdate(lu model.LiveUpdate) ManifestBuilder {
    74  	return b.WithLiveUpdateAtIndex(lu, 0)
    75  }
    76  
    77  func (b ManifestBuilder) WithLiveUpdateAtIndex(lu model.LiveUpdate, index int) ManifestBuilder {
    78  	if len(b.iTargets) <= index {
    79  		b.f.T().Fatalf("WithLiveUpdateAtIndex: index %d out of range -- (manifestBuilder has %d image targets)", index, len(b.iTargets))
    80  	}
    81  
    82  	iTarg := b.iTargets[index]
    83  	switch bd := iTarg.BuildDetails.(type) {
    84  	case model.DockerBuild:
    85  		bd.LiveUpdate = lu
    86  		b.iTargets[index] = iTarg.WithBuildDetails(bd)
    87  	case model.CustomBuild:
    88  		bd.LiveUpdate = lu
    89  		b.iTargets[index] = iTarg.WithBuildDetails(bd)
    90  	default:
    91  		b.f.T().Fatalf("unrecognized buildDetails type: %v", bd)
    92  	}
    93  	return b
    94  }
    95  
    96  func (b ManifestBuilder) WithResourceDeps(deps ...string) ManifestBuilder {
    97  	b.resourceDeps = deps
    98  	return b
    99  }
   100  
   101  func (b ManifestBuilder) Build() model.Manifest {
   102  	var rds []model.ManifestName
   103  	for _, dep := range b.resourceDeps {
   104  		rds = append(rds, model.ManifestName(dep))
   105  	}
   106  
   107  	if b.k8sYAML != "" {
   108  		return assembleK8s(
   109  			model.Manifest{Name: b.name, ResourceDependencies: rds},
   110  			model.K8sTarget{YAML: b.k8sYAML, ExtraPodSelectors: b.k8sPodSelectors},
   111  			b.iTargets...)
   112  	}
   113  
   114  	if len(b.dcConfigPaths) > 0 {
   115  		return assembleDC(
   116  			model.Manifest{Name: b.name, ResourceDependencies: rds},
   117  			model.DockerComposeTarget{
   118  				Name:        model.TargetName(b.name),
   119  				ConfigPaths: b.dcConfigPaths,
   120  			},
   121  			b.iTargets...)
   122  	}
   123  
   124  	if b.localCmd != "" {
   125  		lt := model.NewLocalTarget(model.TargetName(b.name), model.ToShellCmd(b.localCmd), b.f.Path(), b.localDeps)
   126  		return model.Manifest{Name: b.name, ResourceDependencies: rds}.WithDeployTarget(lt)
   127  	}
   128  
   129  	b.f.T().Fatalf("No deploy target specified: %s", b.name)
   130  	return model.Manifest{}
   131  }
   132  
   133  type Fixture interface {
   134  	T() testing.TB
   135  	Path() string
   136  	JoinPath(ps ...string) string
   137  	MkdirAll(p string)
   138  }