github.com/rigado/snapd@v2.42.5-go-mod+incompatible/cmd/snap/cmd_aliases.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2016 Canonical Ltd
     5   *
     6   * This program is free software: you can redistribute it and/or modify
     7   * it under the terms of the GNU General Public License version 3 as
     8   * published by the Free Software Foundation.
     9   *
    10   * This program is distributed in the hope that it will be useful,
    11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13   * GNU General Public License for more details.
    14   *
    15   * You should have received a copy of the GNU General Public License
    16   * along with this program.  If not, see <http://www.gnu.org/licenses/>.
    17   *
    18   */
    19  
    20  package main
    21  
    22  import (
    23  	"fmt"
    24  	"sort"
    25  	"strings"
    26  
    27  	"github.com/jessevdk/go-flags"
    28  
    29  	"github.com/snapcore/snapd/client"
    30  	"github.com/snapcore/snapd/i18n"
    31  )
    32  
    33  type cmdAliases struct {
    34  	clientMixin
    35  	Positionals struct {
    36  		Snap installedSnapName `positional-arg-name:"<snap>"`
    37  	} `positional-args:"true"`
    38  }
    39  
    40  var shortAliasesHelp = i18n.G("List aliases in the system")
    41  var longAliasesHelp = i18n.G(`
    42  The aliases command lists all aliases available in the system and their status.
    43  
    44  $ snap aliases <snap>
    45  
    46  Lists only the aliases defined by the specified snap.
    47  
    48  An alias noted as undefined means it was explicitly enabled or disabled but is
    49  not defined in the current revision of the snap, possibly temporarily (e.g.
    50  because of a revert). This can cleared with 'snap alias --reset'.
    51  `)
    52  
    53  func init() {
    54  	addCommand("aliases", shortAliasesHelp, longAliasesHelp, func() flags.Commander {
    55  		return &cmdAliases{}
    56  	}, nil, nil)
    57  }
    58  
    59  type aliasInfo struct {
    60  	Snap    string
    61  	Command string
    62  	Alias   string
    63  	Status  string
    64  	Auto    string
    65  }
    66  
    67  type aliasInfos []*aliasInfo
    68  
    69  func (infos aliasInfos) Len() int      { return len(infos) }
    70  func (infos aliasInfos) Swap(i, j int) { infos[i], infos[j] = infos[j], infos[i] }
    71  func (infos aliasInfos) Less(i, j int) bool {
    72  	if infos[i].Snap < infos[j].Snap {
    73  		return true
    74  	}
    75  	if infos[i].Snap == infos[j].Snap {
    76  		if infos[i].Command < infos[j].Command {
    77  			return true
    78  		}
    79  		if infos[i].Command == infos[j].Command {
    80  			if infos[i].Alias < infos[j].Alias {
    81  				return true
    82  			}
    83  		}
    84  	}
    85  	return false
    86  }
    87  
    88  func (x *cmdAliases) Execute(args []string) error {
    89  	if len(args) > 0 {
    90  		return ErrExtraArgs
    91  	}
    92  
    93  	allStatuses, err := x.client.Aliases()
    94  	if err != nil {
    95  		return err
    96  	}
    97  
    98  	var infos aliasInfos
    99  	filterSnap := string(x.Positionals.Snap)
   100  	if filterSnap != "" {
   101  		allStatuses = map[string]map[string]client.AliasStatus{
   102  			filterSnap: allStatuses[filterSnap],
   103  		}
   104  	}
   105  	for snapName, aliasStatuses := range allStatuses {
   106  		for alias, aliasStatus := range aliasStatuses {
   107  			infos = append(infos, &aliasInfo{
   108  				Snap:    snapName,
   109  				Command: aliasStatus.Command,
   110  				Alias:   alias,
   111  				Status:  aliasStatus.Status,
   112  				Auto:    aliasStatus.Auto,
   113  			})
   114  		}
   115  	}
   116  
   117  	if len(infos) > 0 {
   118  		w := tabWriter()
   119  		fmt.Fprintln(w, i18n.G("Command\tAlias\tNotes"))
   120  		defer w.Flush()
   121  
   122  		sort.Sort(infos)
   123  
   124  		for _, info := range infos {
   125  			var notes []string
   126  			if info.Status != "auto" {
   127  				notes = append(notes, info.Status)
   128  				if info.Status == "manual" && info.Auto != "" {
   129  					notes = append(notes, "override")
   130  				}
   131  			}
   132  			notesStr := strings.Join(notes, ",")
   133  			if notesStr == "" {
   134  				notesStr = "-"
   135  			}
   136  			fmt.Fprintf(w, "%s\t%s\t%s\n", info.Command, info.Alias, notesStr)
   137  		}
   138  	} else {
   139  		if filterSnap != "" {
   140  			fmt.Fprintf(Stderr, i18n.G("No aliases are currently defined for snap %q.\n"), filterSnap)
   141  		} else {
   142  			fmt.Fprintln(Stderr, i18n.G("No aliases are currently defined."))
   143  		}
   144  		fmt.Fprintln(Stderr, i18n.G("\nUse 'snap help alias' to learn how to create aliases manually."))
   145  	}
   146  	return nil
   147  }