...

Source file src/github.com/bazelbuild/rules_go/go/tools/gopackagesdriver/packageregistry.go

Documentation: github.com/bazelbuild/rules_go/go/tools/gopackagesdriver

     1  // Copyright 2021 The Bazel Authors. All rights reserved.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //    http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package main
    16  
    17  import (
    18  	"fmt"
    19  	"os"
    20  	"strconv"
    21  	"strings"
    22  )
    23  
    24  type PackageRegistry struct {
    25  	packagesByID map[string]*FlatPackage
    26  	stdlib       map[string]string
    27  	bazelVersion []int
    28  }
    29  
    30  func NewPackageRegistry(bazelVersion string, pkgs ...*FlatPackage) *PackageRegistry {
    31  	pr := &PackageRegistry{
    32  		packagesByID: map[string]*FlatPackage{},
    33  		stdlib:       map[string]string{},
    34  		bazelVersion: parseVersion(bazelVersion),
    35  	}
    36  	pr.Add(pkgs...)
    37  	return pr
    38  }
    39  
    40  func (pr *PackageRegistry) Add(pkgs ...*FlatPackage) *PackageRegistry {
    41  	for _, pkg := range pkgs {
    42  		pr.packagesByID[pkg.ID] = pkg
    43  
    44  		if pkg.IsStdlib() {
    45  			pr.stdlib[pkg.PkgPath] = pkg.ID
    46  		}
    47  	}
    48  	return pr
    49  }
    50  
    51  func (pr *PackageRegistry) ResolvePaths(prf PathResolverFunc) error {
    52  	for _, pkg := range pr.packagesByID {
    53  		pkg.ResolvePaths(prf)
    54  		pkg.FilterFilesForBuildTags()
    55  	}
    56  	return nil
    57  }
    58  
    59  // ResolveImports adds stdlib imports to packages. This is required because
    60  // stdlib packages are not part of the JSON file exports as bazel is unaware of
    61  // them.
    62  func (pr *PackageRegistry) ResolveImports() error {
    63  	resolve := func(importPath string) string {
    64  		if pkgID, ok := pr.stdlib[importPath]; ok {
    65  			return pkgID
    66  		}
    67  
    68  		return ""
    69  	}
    70  
    71  	for _, pkg := range pr.packagesByID {
    72  		if err := pkg.ResolveImports(resolve); err != nil {
    73  			return err
    74  		}
    75  		testFp := pkg.MoveTestFiles()
    76  		if testFp != nil {
    77  			pr.packagesByID[testFp.ID] = testFp
    78  		}
    79  	}
    80  
    81  	return nil
    82  }
    83  
    84  func (pr *PackageRegistry) walk(acc map[string]*FlatPackage, root string) {
    85  	pkg := pr.packagesByID[root]
    86  
    87  	if pkg == nil {
    88  		fmt.Fprintf(os.Stderr, "Error: package ID not found %v\n", root)
    89  		return
    90  	}
    91  
    92  	acc[pkg.ID] = pkg
    93  	for _, pkgID := range pkg.Imports {
    94  		if _, ok := acc[pkgID]; !ok {
    95  			pr.walk(acc, pkgID)
    96  		}
    97  	}
    98  }
    99  
   100  func (pr *PackageRegistry) Match(labels []string) ([]string, []*FlatPackage) {
   101  	roots := map[string]struct{}{}
   102  
   103  	for _, label := range labels {
   104  		// When packagesdriver is ran from rules go, rulesGoRepositoryName will just be @
   105  		if pr.bazelVersion[0] >= 6 &&
   106  			!strings.HasPrefix(label, "@") {
   107  			// Canonical labels is only since Bazel 6.0.0
   108  			label = fmt.Sprintf("@%s", label)
   109  		}
   110  
   111  		if label == RulesGoStdlibLabel {
   112  			// For stdlib, we need to append all the subpackages as roots
   113  			// since RulesGoStdLibLabel doesn't actually show up in the stdlib pkg.json
   114  			for _, pkg := range pr.packagesByID {
   115  				if pkg.Standard {
   116  					roots[pkg.ID] = struct{}{}
   117  				}
   118  			}
   119  		} else {
   120  			roots[label] = struct{}{}
   121  			// If an xtest package exists for this package add it to the roots
   122  			if _, ok := pr.packagesByID[label+"_xtest"]; ok {
   123  				roots[label+"_xtest"] = struct{}{}
   124  			}
   125  		}
   126  	}
   127  
   128  	walkedPackages := map[string]*FlatPackage{}
   129  	retRoots := make([]string, 0, len(roots))
   130  	for rootPkg := range roots {
   131  		retRoots = append(retRoots, rootPkg)
   132  		pr.walk(walkedPackages, rootPkg)
   133  	}
   134  
   135  	retPkgs := make([]*FlatPackage, 0, len(walkedPackages))
   136  	for _, pkg := range walkedPackages {
   137  		retPkgs = append(retPkgs, pkg)
   138  	}
   139  
   140  	return retRoots, retPkgs
   141  }
   142  
   143  func parseVersion(v string) []int {
   144  	parts := strings.Split(v, ".")
   145  	version := make([]int, len(parts))
   146  
   147  	var err error
   148  	for i, p := range parts {
   149  		version[i], err = strconv.Atoi(p)
   150  		if err != nil {
   151  			// Failsafe default
   152  			return []int{6, 0, 0}
   153  		}
   154  	}
   155  
   156  	return version
   157  }
   158  

View as plain text