github.com/GoogleContainerTools/skaffold@v1.39.18/pkg/skaffold/initializer/build/json.go (about)

     1  /*
     2  Copyright 2020 The Skaffold Authors
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package build
    18  
    19  import (
    20  	"encoding/json"
    21  	"errors"
    22  	"io"
    23  
    24  	"github.com/GoogleContainerTools/skaffold/pkg/skaffold/docker"
    25  )
    26  
    27  func printAnalysis(out io.Writer, enableNewFormat bool, skipBuild bool, pairs []ArtifactInfo, unresolvedBuilderConfigs []InitBuilder, unresolvedImages []string) error {
    28  	if !enableNewFormat {
    29  		return PrintAnalyzeOldFormat(out, skipBuild, pairs, unresolvedBuilderConfigs, unresolvedImages)
    30  	}
    31  
    32  	return PrintAnalyzeJSON(out, skipBuild, pairs, unresolvedBuilderConfigs, unresolvedImages)
    33  }
    34  
    35  // TODO(nkubala): make these private again once DoInit() relinquishes control of the builder/image processing
    36  func PrintAnalyzeOldFormat(out io.Writer, skipBuild bool, pairs []ArtifactInfo, unresolvedBuilders []InitBuilder, unresolvedImages []string) error {
    37  	if !skipBuild && len(unresolvedBuilders) == 0 {
    38  		return errors.New("one or more valid Dockerfiles must be present to build images with skaffold; please provide at least one Dockerfile and try again, or run `skaffold init --skip-build`")
    39  	}
    40  
    41  	a := struct {
    42  		Dockerfiles []string `json:"dockerfiles,omitempty"`
    43  		Images      []string `json:"images,omitempty"`
    44  	}{Images: unresolvedImages}
    45  
    46  	for _, pair := range pairs {
    47  		if pair.Builder.Name() == docker.Name {
    48  			a.Dockerfiles = append(a.Dockerfiles, pair.Builder.Path())
    49  		}
    50  		a.Images = append(a.Images, pair.ImageName)
    51  	}
    52  	for _, config := range unresolvedBuilders {
    53  		if config.Name() == docker.Name {
    54  			a.Dockerfiles = append(a.Dockerfiles, config.Path())
    55  		}
    56  	}
    57  
    58  	return json.NewEncoder(out).Encode(a)
    59  }
    60  
    61  // printAnalyzeJSON takes the automatically resolved builder/image pairs, the unresolved images, and the unresolved builders, and generates
    62  // a JSON string containing builder config information,
    63  func PrintAnalyzeJSON(out io.Writer, skipBuild bool, pairs []ArtifactInfo, unresolvedBuilders []InitBuilder, unresolvedImages []string) error {
    64  	if !skipBuild && len(unresolvedBuilders) == 0 {
    65  		return errors.New("one or more valid Dockerfiles must be present to build images with skaffold; please provide at least one Dockerfile and try again, or run `skaffold init --skip-build`")
    66  	}
    67  
    68  	// Build JSON output. Example schema is below:
    69  	// {
    70  	//     "builders":[
    71  	//         {
    72  	//             "name":"Docker",
    73  	//             "payload":"path/to/Dockerfile"
    74  	//         },
    75  	//         {
    76  	//             "name":"Name of Builder",
    77  	//             "payload": { // Payload structure may vary depending on builder type
    78  	//                 "path":"path/to/builder.config",
    79  	//                 "targetImage":"gcr.io/project/images",
    80  	//                 ...
    81  	//             }
    82  	//         },
    83  	//     ],
    84  	//     "images":[
    85  	//         {"name":"gcr.io/project/images", "foundMatch":"true"}, // No need to prompt for this image since its builder was automatically resolved
    86  	//         {"name":"another/image", "foundMatch":"false"},
    87  	//     ],
    88  	// }
    89  	//
    90  	// "builders" is the list of builder configurations, and contains a builder name and a builder-specific payload
    91  	// "images" contains an image name and a boolean that indicates whether a builder/image pair can be automatically resolved (true) or if it requires prompting (false)
    92  	type Builder struct {
    93  		Name    string      `json:"name,omitempty"`
    94  		Payload InitBuilder `json:"payload"`
    95  	}
    96  	type Image struct {
    97  		Name       string `json:"name"`
    98  		FoundMatch bool   `json:"foundMatch"`
    99  	}
   100  	a := struct {
   101  		Builders []Builder `json:"builders,omitempty"`
   102  		Images   []Image   `json:"images,omitempty"`
   103  	}{}
   104  
   105  	for _, pair := range pairs {
   106  		a.Builders = append(a.Builders, Builder{Name: pair.Builder.Name(), Payload: pair.Builder})
   107  		a.Images = append(a.Images, Image{Name: pair.ImageName, FoundMatch: true})
   108  	}
   109  	for _, config := range unresolvedBuilders {
   110  		a.Builders = append(a.Builders, Builder{Name: config.Name(), Payload: config})
   111  	}
   112  	for _, image := range unresolvedImages {
   113  		a.Images = append(a.Images, Image{Name: image, FoundMatch: false})
   114  	}
   115  
   116  	return json.NewEncoder(out).Encode(a)
   117  }