go.etcd.io/etcd@v3.3.27+incompatible/etcdctl/ctlv2/command/ls_command.go (about)

     1  // Copyright 2015 The etcd Authors
     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 command
    16  
    17  import (
    18  	"fmt"
    19  
    20  	"github.com/coreos/etcd/client"
    21  	"github.com/urfave/cli"
    22  )
    23  
    24  func NewLsCommand() cli.Command {
    25  	return cli.Command{
    26  		Name:      "ls",
    27  		Usage:     "retrieve a directory",
    28  		ArgsUsage: "[key]",
    29  		Flags: []cli.Flag{
    30  			cli.BoolFlag{Name: "sort", Usage: "returns result in sorted order"},
    31  			cli.BoolFlag{Name: "recursive, r", Usage: "returns all key names recursively for the given path"},
    32  			cli.BoolFlag{Name: "p", Usage: "append slash (/) to directories"},
    33  			cli.BoolFlag{Name: "quorum, q", Usage: "require quorum for get request"},
    34  		},
    35  		Action: func(c *cli.Context) error {
    36  			lsCommandFunc(c, mustNewKeyAPI(c))
    37  			return nil
    38  		},
    39  	}
    40  }
    41  
    42  // lsCommandFunc executes the "ls" command.
    43  func lsCommandFunc(c *cli.Context, ki client.KeysAPI) {
    44  	key := "/"
    45  	if len(c.Args()) != 0 {
    46  		key = c.Args()[0]
    47  	}
    48  
    49  	sort := c.Bool("sort")
    50  	recursive := c.Bool("recursive")
    51  	quorum := c.Bool("quorum")
    52  
    53  	ctx, cancel := contextWithTotalTimeout(c)
    54  	resp, err := ki.Get(ctx, key, &client.GetOptions{Sort: sort, Recursive: recursive, Quorum: quorum})
    55  	cancel()
    56  	if err != nil {
    57  		handleError(c, ExitServerError, err)
    58  	}
    59  
    60  	printLs(c, resp)
    61  }
    62  
    63  // printLs writes a response out in a manner similar to the `ls` command in unix.
    64  // Non-empty directories list their contents and files list their name.
    65  func printLs(c *cli.Context, resp *client.Response) {
    66  	if c.GlobalString("output") == "simple" {
    67  		if !resp.Node.Dir {
    68  			fmt.Println(resp.Node.Key)
    69  		}
    70  		for _, node := range resp.Node.Nodes {
    71  			rPrint(c, node)
    72  		}
    73  	} else {
    74  		// user wants JSON or extended output
    75  		printResponseKey(resp, c.GlobalString("output"))
    76  	}
    77  }
    78  
    79  // rPrint recursively prints out the nodes in the node structure.
    80  func rPrint(c *cli.Context, n *client.Node) {
    81  	if n.Dir && c.Bool("p") {
    82  		fmt.Println(fmt.Sprintf("%v/", n.Key))
    83  	} else {
    84  		fmt.Println(n.Key)
    85  	}
    86  
    87  	for _, node := range n.Nodes {
    88  		rPrint(c, node)
    89  	}
    90  }