func GenerateProduct()

in mmv1/main.go [192:322]


func GenerateProduct(productChannel chan string, providerToGenerate provider.Provider, productsForVersionChannel chan *api.Product, startTime time.Time, productsToGenerate []string, resourceToGenerate, overrideDirectory string, generateCode, generateDocs bool) {

	defer wg.Done()
	productName := <-productChannel

	productYamlPath := path.Join(productName, "product.yaml")

	var productOverridePath string
	if overrideDirectory != "" {
		productOverridePath = filepath.Join(overrideDirectory, productName, "product.yaml")
	}

	_, baseProductErr := os.Stat(productYamlPath)
	baseProductExists := !errors.Is(baseProductErr, os.ErrNotExist)

	_, overrideProductErr := os.Stat(productOverridePath)
	overrideProductExists := !errors.Is(overrideProductErr, os.ErrNotExist)

	if !(baseProductExists || overrideProductExists) {
		log.Fatalf("%s does not contain a product.yaml file", productName)
	}

	productApi := &api.Product{}

	if overrideProductExists {
		if baseProductExists {
			api.Compile(productYamlPath, productApi, overrideDirectory)
			overrideApiProduct := &api.Product{}
			api.Compile(productOverridePath, overrideApiProduct, overrideDirectory)

			api.Merge(reflect.ValueOf(productApi), reflect.ValueOf(*overrideApiProduct))
		} else {
			api.Compile(productOverridePath, productApi, overrideDirectory)
		}
	} else {
		api.Compile(productYamlPath, productApi, overrideDirectory)
	}

	var resources []*api.Resource = make([]*api.Resource, 0)

	if !productApi.ExistsAtVersionOrLower(*version) {
		log.Printf("%s does not have a '%s' version, skipping", productName, *version)
		return
	}

	resourceFiles, err := filepath.Glob(fmt.Sprintf("%s/*", productName))
	if err != nil {
		log.Fatalf("Cannot get resources files: %v", err)
	}
	// Base resource loop
	for _, resourceYamlPath := range resourceFiles {
		if filepath.Base(resourceYamlPath) == "product.yaml" || filepath.Ext(resourceYamlPath) != ".yaml" {
			continue
		}

		if overrideDirectory != "" {
			// skip if resource will be merged in the override loop
			resourceOverridePath := filepath.Join(overrideDirectory, resourceYamlPath)
			_, overrideResourceErr := os.Stat(resourceOverridePath)
			overrideResourceExists := !errors.Is(overrideResourceErr, os.ErrNotExist)
			if overrideResourceExists {
				continue
			}
		}

		resource := &api.Resource{}
		api.Compile(resourceYamlPath, resource, overrideDirectory)
		resource.SourceYamlFile = resourceYamlPath

		resource.TargetVersionName = *version
		resource.Properties = resource.AddLabelsRelatedFields(resource.PropertiesWithExcluded(), nil)
		resource.SetDefault(productApi)
		resource.Validate()
		resources = append(resources, resource)
	}

	// Override Resource Loop
	if overrideDirectory != "" {
		productOverrideDir := filepath.Dir(productOverridePath)
		overrideFiles, err := filepath.Glob(fmt.Sprintf("%s/*", productOverrideDir))
		if err != nil {
			log.Fatalf("Cannot get override files: %v", err)
		}
		for _, overrideYamlPath := range overrideFiles {
			if filepath.Base(overrideYamlPath) == "product.yaml" || filepath.Ext(overrideYamlPath) != ".yaml" {
				continue
			}

			resource := &api.Resource{}

			baseResourcePath := filepath.Join(productName, filepath.Base(overrideYamlPath))
			_, baseResourceErr := os.Stat(baseResourcePath)
			baseResourceExists := !errors.Is(baseResourceErr, os.ErrNotExist)
			if baseResourceExists {
				api.Compile(baseResourcePath, resource, overrideDirectory)
				overrideResource := &api.Resource{}
				api.Compile(overrideYamlPath, overrideResource, overrideDirectory)
				api.Merge(reflect.ValueOf(resource), reflect.ValueOf(*overrideResource))
			} else {
				api.Compile(overrideYamlPath, resource, overrideDirectory)
			}

			resource.TargetVersionName = *version
			resource.Properties = resource.AddLabelsRelatedFields(resource.PropertiesWithExcluded(), nil)
			resource.SetDefault(productApi)
			resource.Validate()
			resources = append(resources, resource)
		}

		// Sort resources by name
		sort.Slice(resources, func(i, j int) bool {
			return resources[i].Name < resources[j].Name
		})

	}

	productApi.Objects = resources
	productApi.Validate()

	providerToGenerate = setProvider(*forceProvider, *version, productApi, startTime)

	productsForVersionChannel <- productApi

	if !slices.Contains(productsToGenerate, productName) {
		log.Printf("%s not specified, skipping generation", productName)
		return
	}

	log.Printf("%s: Generating files", productName)
	providerToGenerate.Generate(*outputPath, productName, resourceToGenerate, generateCode, generateDocs)
}