golang.org/x/build@v0.0.0-20240506185731-218518f32b70/cmd/gomote/ls.go (about)

     1  // Copyright 2015 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"context"
     9  	"flag"
    10  	"fmt"
    11  	"os"
    12  	"strings"
    13  
    14  	"golang.org/x/build/internal/gomote/protos"
    15  )
    16  
    17  func ls(args []string) error {
    18  	fs := flag.NewFlagSet("ls", flag.ContinueOnError)
    19  	fs.Usage = func() {
    20  		fmt.Fprintln(os.Stderr, "ls usage: gomote ls [ls-opts] [instance] [dir]")
    21  		fmt.Fprintln(os.Stderr, "")
    22  		fmt.Fprintln(os.Stderr, "Instance name is optional if a group is specified.")
    23  		fs.PrintDefaults()
    24  		os.Exit(1)
    25  	}
    26  	var recursive bool
    27  	fs.BoolVar(&recursive, "R", false, "recursive")
    28  	var digest bool
    29  	fs.BoolVar(&digest, "d", false, "get file digests")
    30  	var skip string
    31  	fs.StringVar(&skip, "skip", "", "comma-separated list of relative directories to skip (use forward slashes)")
    32  	fs.Parse(args)
    33  
    34  	ctx := context.Background()
    35  	dir := "."
    36  	var lsSet []string
    37  	switch fs.NArg() {
    38  	case 0:
    39  		// With no arguments, we need an active group to do anything useful.
    40  		if activeGroup == nil {
    41  			fmt.Fprintln(os.Stderr, "error: no group specified")
    42  			fs.Usage()
    43  		}
    44  		for _, inst := range activeGroup.Instances {
    45  			lsSet = append(lsSet, inst)
    46  		}
    47  	case 1:
    48  		// Ambiguous case. Check if it's a real instance, if not, treat it
    49  		// as a directory.
    50  		if err := doPing(ctx, fs.Arg(0)); instanceDoesNotExist(err) {
    51  			// Not an instance.
    52  			for _, inst := range activeGroup.Instances {
    53  				lsSet = append(lsSet, inst)
    54  			}
    55  			dir = fs.Arg(0)
    56  		} else if err == nil {
    57  			// It's an instance.
    58  			lsSet = []string{fs.Arg(0)}
    59  		} else {
    60  			return fmt.Errorf("failed to ping %q: %w", fs.Arg(0), err)
    61  		}
    62  	case 2:
    63  		// Instance and directory is specified.
    64  		lsSet = []string{fs.Arg(0)}
    65  		dir = fs.Arg(1)
    66  	default:
    67  		fmt.Fprintln(os.Stderr, "error: too many arguments")
    68  		fs.Usage()
    69  	}
    70  	for _, inst := range lsSet {
    71  		client := gomoteServerClient(ctx)
    72  		resp, err := client.ListDirectory(ctx, &protos.ListDirectoryRequest{
    73  			GomoteId:  inst,
    74  			Directory: dir,
    75  			Recursive: recursive,
    76  			SkipFiles: strings.Split(skip, ","),
    77  			Digest:    digest,
    78  		})
    79  		if err != nil {
    80  			return fmt.Errorf("unable to ls: %w", err)
    81  		}
    82  		if len(lsSet) > 1 {
    83  			fmt.Fprintf(os.Stdout, "# %s\n", inst)
    84  		}
    85  		for _, entry := range resp.GetEntries() {
    86  			fmt.Fprintf(os.Stdout, "%s\n", entry)
    87  		}
    88  		if len(lsSet) > 1 {
    89  			fmt.Fprintln(os.Stdout)
    90  		}
    91  	}
    92  	return nil
    93  }