...

Source file src/edge-infra.dev/hack/build/rules/container/gazelle/language/generate.go

Documentation: edge-infra.dev/hack/build/rules/container/gazelle/language

     1  package container
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/bazelbuild/bazel-gazelle/language"
    10  	"github.com/bazelbuild/bazel-gazelle/resolve"
    11  	"github.com/bazelbuild/bazel-gazelle/rule"
    12  	"github.com/bazelbuild/buildtools/build"
    13  
    14  	"edge-infra.dev/hack/build/rules/gazelle/constants"
    15  )
    16  
    17  const (
    18  	visibility       = "visibility"
    19  	visibilityPublic = "//visibility:public"
    20  )
    21  
    22  func (c *Container) GenerateRules(args language.GenerateArgs) language.GenerateResult {
    23  	gr := language.GenerateResult{
    24  		Gen:     []*rule.Rule{},
    25  		Imports: []any{},
    26  	}
    27  
    28  	files := []string{}
    29  	for _, f := range args.RegularFiles {
    30  		if strings.HasSuffix(f, ".bzl") {
    31  			files = append(files, f)
    32  		}
    33  	}
    34  
    35  	if len(files) == 0 {
    36  		return language.GenerateResult{}
    37  	}
    38  
    39  	pushRules := []*rule.Rule{}
    40  	pushImports := []resolve.ImportSpec{}
    41  	var err error
    42  	for _, file := range files {
    43  		pushRules, pushImports, err = generateTPPushRulesFromFile(file, args, pushRules, pushImports)
    44  		if err != nil {
    45  			fmt.Println(fmt.Errorf("error generating rule: %w", err))
    46  			return language.GenerateResult{}
    47  		}
    48  	}
    49  
    50  	containerImports := make([]interface{}, len(pushRules))
    51  	for i, importSpec := range pushImports {
    52  		containerImports[i] = importSpec
    53  	}
    54  
    55  	gr.Gen = append(gr.Gen, pushRules...)
    56  	gr.Imports = append(gr.Imports, containerImports...)
    57  
    58  	return gr
    59  }
    60  
    61  func generateTPPushRulesFromFile(file string, args language.GenerateArgs, pushRules []*rule.Rule, importSpecs []resolve.ImportSpec) ([]*rule.Rule, []resolve.ImportSpec, error) {
    62  	bzlBytes, err := os.ReadFile(filepath.Join(args.Dir, file))
    63  	if err != nil {
    64  		return pushRules, importSpecs, fmt.Errorf("file %s found, but error reading: %w", file, err)
    65  	}
    66  
    67  	bazelFile, err := build.ParseBzl(file, bzlBytes)
    68  	if err != nil {
    69  		err = fmt.Errorf("file %s read, but error parsing to bzl file: %w", file, err)
    70  		fmt.Println(err)
    71  		return pushRules, importSpecs, err
    72  	}
    73  
    74  	tpDepRules := bazelFile.Rules(ThirdPartyContainerDepRuleName)
    75  	if len(tpDepRules) == 0 {
    76  		return pushRules, importSpecs, nil
    77  	}
    78  
    79  	bazelConsts := constants.BazelConstMap{}
    80  	bazelConsts, err = constants.ResolveConstants(args, bazelFile, bazelConsts)
    81  	if err != nil {
    82  		return pushRules, importSpecs, fmt.Errorf("error parsing constants: %w", err)
    83  	}
    84  
    85  	for _, tpRule := range tpDepRules {
    86  		pullName := constants.ResolveAttr(tpRule, "name", bazelConsts)
    87  		pullName = strings.ReplaceAll(pullName, "-", "_")
    88  
    89  		registry := constants.ResolveAttr(tpRule, "registry", bazelConsts)
    90  		repository := constants.ResolveAttr(tpRule, "repository", bazelConsts)
    91  		tag := constants.ResolveAttr(tpRule, "tag", bazelConsts)
    92  
    93  		destinationRepo := constants.ResolveAttr(tpRule, "destination_repo", bazelConsts)
    94  		var destinationImageName string
    95  
    96  		if destinationRepo != "" {
    97  			destinationImageName = destinationRepo
    98  		} else {
    99  			destinationImageName = repository
   100  			if registry != "index.docker.io" {
   101  				destinationImageName = fmt.Sprintf("%s/%s", registry, destinationImageName)
   102  			}
   103  		}
   104  
   105  		name := fmt.Sprintf("%s_container_push", pullName)
   106  		tpPushRule := rule.NewRule(ContainerPushRuleName, name)
   107  
   108  		makeDefaults(tpPushRule)
   109  
   110  		// take attrs from third_party_container_dep and set container_push attrs
   111  		tpPushRule.SetAttr("name", name)
   112  		tpPushRule.SetAttr("image_name", destinationImageName)
   113  		tpPushRule.SetAttr("image", fmt.Sprintf("@%s//:%s", pullName, pullName))
   114  		tpPushRule.SetAttr("digest", fmt.Sprintf("@%s//:digest", pullName))
   115  		tpPushRule.SetAttr("repository_file", "//hack/build/rules/container:thirdparty-repo")
   116  		tpPushRule.SetAttr("from_third_party", true)
   117  
   118  		importSpec := toImportSpec(tpPushRule, args.File)
   119  
   120  		// Optionals
   121  		if tag != "" {
   122  			tpPushRule.SetAttr("tag", tag)
   123  		}
   124  
   125  		pushRules = append(pushRules, tpPushRule)
   126  		importSpecs = append(importSpecs, importSpec)
   127  	}
   128  
   129  	return pushRules, importSpecs, nil
   130  }
   131  
   132  func makeDefaults(r *rule.Rule) {
   133  	r.SetAttr(visibility, []string{visibilityPublic})
   134  }
   135  

View as plain text