...

Source file src/edge-infra.dev/pkg/tools/hack/cmd/owners/list.go

Documentation: edge-infra.dev/pkg/tools/hack/cmd/owners

     1  package owners
     2  
     3  // print tree of owners files + dirs they cover
     4  
     5  import (
     6  	"context"
     7  	"flag"
     8  	"fmt"
     9  	"io/fs"
    10  	"path/filepath"
    11  	"strings"
    12  
    13  	"slices"
    14  
    15  	"github.com/peterbourgon/ff/v3"
    16  	"github.com/peterbourgon/ff/v3/ffcli"
    17  
    18  	"edge-infra.dev/pkg/lib/text/drawing"
    19  )
    20  
    21  type list struct {
    22  	*owners
    23  
    24  	dir string
    25  }
    26  
    27  func newList(o *owners) *ffcli.Command {
    28  	l := &list{owners: o}
    29  
    30  	fs := flag.NewFlagSet("hack owners list", flag.ExitOnError)
    31  	l.owners.RegisterFlags(fs)
    32  
    33  	fs.StringVar(&l.dir, "directory", "",
    34  		"verify that the policy-bot config is valid")
    35  
    36  	return &ffcli.Command{
    37  		Name:    "list",
    38  		FlagSet: fs,
    39  		Exec:    l.Exec,
    40  		Options: []ff.Option{
    41  			ff.WithEnvVarNoPrefix(),
    42  		},
    43  	}
    44  }
    45  
    46  // print all paths and their owners
    47  func (l *list) Exec(_ context.Context, _ []string) error {
    48  	// collect the list of paths
    49  	names, _, err := l.collectOwners()
    50  	if err != nil {
    51  		return err
    52  	}
    53  
    54  	// if a user defined a spefic dir attempt to print the structure
    55  	if l.dir != "" {
    56  		if slices.Contains(names, l.dir) {
    57  			return listDir(l.dir)
    58  		}
    59  		return fmt.Errorf("directory provided by user doesnt have an OWNERS file")
    60  	}
    61  
    62  	// otherwise print everything
    63  	for _, name := range names {
    64  		err := listDir(name)
    65  		if err != nil {
    66  			return err
    67  		}
    68  	}
    69  	return nil
    70  }
    71  
    72  func listDir(name string) error {
    73  	ownerName := fmt.Sprintf("%s/%s", name, "OWNERS")
    74  
    75  	rootNode := &drawing.StringTree{
    76  		Data: "/",
    77  	}
    78  	nodes := map[string]*drawing.StringTree{}
    79  	err := filepath.WalkDir(name, func(path string, info fs.DirEntry, err error) error {
    80  		if err != nil {
    81  			return err
    82  		}
    83  
    84  		for _, x := range ignoreList {
    85  			if strings.Contains(path, x) {
    86  				return filepath.SkipDir
    87  			}
    88  		}
    89  
    90  		// check if the current dir is in the ignore list
    91  		if info.IsDir() && slices.Contains(ignore, path) {
    92  			// fmt.Println("skipping ignored", path)
    93  			return filepath.SkipDir
    94  		}
    95  
    96  		d, f := filepath.Split(path)
    97  		d = strings.TrimSuffix(d, "/")
    98  
    99  		if d == "" { // pkg/ cmd/
   100  			node := &drawing.StringTree{
   101  				Data: f,
   102  			}
   103  			rootNode.Children = append(rootNode.Children, node)
   104  			nodes[f] = node
   105  			return nil
   106  		}
   107  
   108  		dNode, ok := nodes[d] // cmd pkg/edge
   109  		if !ok {
   110  			dNode = &drawing.StringTree{
   111  				Data: d,
   112  			}
   113  			rootNode.Children = append(rootNode.Children, dNode)
   114  			nodes[d] = dNode
   115  		}
   116  
   117  		fNode, ok := nodes[path]
   118  		if !ok {
   119  			fNode = &drawing.StringTree{
   120  				Data: f,
   121  			}
   122  			if path != name && path != ownerName {
   123  				fNode.Labels = map[string]string{ownerName: ""}
   124  			}
   125  			nodes[path] = fNode
   126  		}
   127  		dNode.Children = append(dNode.Children, fNode)
   128  
   129  		return nil
   130  	})
   131  	if err != nil {
   132  		return fmt.Errorf("failed to walk filesystem: %w", err)
   133  	}
   134  	rootNode.Print()
   135  	return nil
   136  }
   137  

View as plain text