// inferBuildTypes infers build status and mismatches between source and docker builders func (c *AppConfig) inferBuildTypes(components app.ComponentReferences) (app.ComponentReferences, error) { errs := []error{} for _, ref := range components { input := ref.Input() // identify whether the input is a builder and whether generation is requested input.ResolvedMatch.Builder = app.IsBuilderMatch(input.ResolvedMatch) generatorInput, err := app.GeneratorInputFromMatch(input.ResolvedMatch) if err != nil && !c.AllowGenerationErrors { errs = append(errs, err) continue } input.ResolvedMatch.GeneratorInput = generatorInput // if the strategy is explicitly Docker, all repos should assume docker if c.Strategy == "docker" && input.Uses != nil { input.Uses.BuildWithDocker() } // if we are expecting build inputs, or get a build input when strategy is not docker, expect to build if c.ExpectToBuild || (input.ResolvedMatch.Builder && c.Strategy != "docker") { input.ExpectToBuild = true } switch { case input.ExpectToBuild && input.ResolvedMatch.IsTemplate(): // TODO: harder - break the template pieces and check if source code can be attached (look for a build config, build image, etc) errs = append(errs, fmt.Errorf("template with source code explicitly attached is not supported - you must either specify the template and source code separately or attach an image to the source code using the '[image]~[code]' form")) continue case input.ExpectToBuild && !input.ResolvedMatch.Builder && input.Uses != nil && !input.Uses.IsDockerBuild(): if len(c.Strategy) == 0 { errs = append(errs, fmt.Errorf("the resolved match %q for component %q cannot build source code - check whether this is the image you want to use, then use --strategy=source to build using source or --strategy=docker to treat this as a Docker base image and set up a layered Docker build", input.ResolvedMatch.Name, ref)) continue } case input.ResolvedMatch.Score != 0.0: errs = append(errs, fmt.Errorf("component %q had only a partial match of %q - if this is the value you want to use, specify it explicitly", input.From, input.ResolvedMatch.Name)) continue } } if len(components) == 0 && c.BinaryBuild { if len(c.Name) == 0 { return nil, fmt.Errorf("you must provide a --name when you don't specify a source repository or base image") } ref := &app.ComponentInput{ From: "--binary", Argument: "--binary", Value: c.Name, ScratchImage: true, ExpectToBuild: true, } components = append(components, ref) } return components, errors.NewAggregate(errs) }
// InferBuildTypes infers build status and mismatches between source and docker builders func InferBuildTypes(components app.ComponentReferences, g *GenerationInputs) (app.ComponentReferences, error) { errs := []error{} for _, ref := range components { input := ref.Input() // identify whether the input is a builder and whether generation is requested input.ResolvedMatch.Builder = app.IsBuilderMatch(input.ResolvedMatch) generatorInput, err := app.GeneratorInputFromMatch(input.ResolvedMatch) if err != nil && !g.AllowGenerationErrors { errs = append(errs, err) continue } input.ResolvedMatch.GeneratorInput = generatorInput // if the strategy is set explicitly, apply it to all repos. // for example, this affects repos specified in the form image~source. if g.Strategy != generate.StrategyUnspecified && input.Uses != nil { input.Uses.SetStrategy(g.Strategy) } // if we are expecting build inputs, or get a build input when strategy is not docker, expect to build if g.ExpectToBuild || (input.ResolvedMatch.Builder && g.Strategy != generate.StrategyDocker) { input.ExpectToBuild = true } switch { case input.ExpectToBuild && input.ResolvedMatch.IsTemplate(): // TODO: harder - break the template pieces and check if source code can be attached (look for a build config, build image, etc) errs = append(errs, errors.New("template with source code explicitly attached is not supported - you must either specify the template and source code separately or attach an image to the source code using the '[image]~[code]' form")) continue } } if len(components) == 0 && g.BinaryBuild && g.Strategy == generate.StrategySource { return nil, errors.New("you must provide a builder image when using the source strategy with a binary build") } if len(components) == 0 && g.BinaryBuild { if len(g.Name) == 0 { return nil, errors.New("you must provide a --name when you don't specify a source repository or base image") } ref := &app.ComponentInput{ From: "--binary", Argument: "--binary", Value: g.Name, ScratchImage: true, ExpectToBuild: true, } components = append(components, ref) } return components, kutilerrors.NewAggregate(errs) }
// validateBuilders confirms that all images associated with components that are to be built, // are builders (or we're using a non-source strategy). func (c *AppConfig) validateBuilders(components app.ComponentReferences) error { if c.Strategy != generate.StrategyUnspecified { return nil } errs := []error{} for _, ref := range components { input := ref.Input() // if we're supposed to build this thing, and the image/imagestream we've matched it to did not come from an explicit CLI argument, // and the image/imagestream we matched to is not explicitly an s2i builder, and we're doing a source-type build, warn the user // that this probably won't work and force them to declare their intention explicitly. if input.ExpectToBuild && input.ResolvedMatch != nil && !app.IsBuilderMatch(input.ResolvedMatch) && input.Uses != nil && input.Uses.GetStrategy() == generate.StrategySource { errs = append(errs, fmt.Errorf("the image match %q for source repository %q does not appear to be a source-to-image builder.\n\n- to attempt to use this image as a source builder, pass \"--strategy=source\"\n- to use it as a base image for a Docker build, pass \"--strategy=docker\"", input.ResolvedMatch.Name, input.Uses)) continue } } return kutilerrors.NewAggregate(errs) }