File: //snap/google-cloud-cli/394/lib/surface/meta/list_commands.py
# -*- coding: utf-8 -*- #
# Copyright 2014 Google LLC. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""A command that lists all possible gcloud commands, optionally with flags."""
from __future__ import absolute_import
from __future__ import division
from __future__ import unicode_literals
import sys
from googlecloudsdk.calliope import base
from googlecloudsdk.calliope import cli_tree
from googlecloudsdk.calliope import walker_util
_LOOKUP_INTERNAL_FLAGS = '_flags_'
_LOOKUP_INTERNAL_NAME = '_name_'
def DisplayFlattenedCommandTree(command, out=None):
"""Displays the commands in the command tree in sorted order on out.
Args:
command: dict, The tree (nested dict) of command/group names.
out: stream, The output stream, sys.stdout if None.
"""
def WalkCommandTree(commands, command, args):
"""Visit each command and group in the CLI command tree.
Each command line is added to the commands list.
Args:
commands: [str], The list of command strings.
command: dict, The tree (nested dict) of command/group names.
args: [str], The subcommand arg prefix.
"""
args_next = args + [command[_LOOKUP_INTERNAL_NAME]]
if commands:
commands.append(' '.join(args_next))
else:
# List the global flags with the root command.
commands.append(' '.join(
args_next + command.get(_LOOKUP_INTERNAL_FLAGS, [])))
if cli_tree.LOOKUP_COMMANDS in command:
for c in command[cli_tree.LOOKUP_COMMANDS]:
name = c.get(_LOOKUP_INTERNAL_NAME, c)
flags = c.get(_LOOKUP_INTERNAL_FLAGS, [])
commands.append(' '.join(args_next + [name] + flags))
if cli_tree.LOOKUP_GROUPS in command:
for g in command[cli_tree.LOOKUP_GROUPS]:
WalkCommandTree(commands, g, args_next)
commands = []
WalkCommandTree(commands, command, [])
if not out:
out = sys.stdout
out.write('\n'.join(sorted(commands)) + '\n')
_COMPLETIONS_PREFIX = '_SC_'
def DisplayCompletions(command, out=None):
"""Displays the static tab completion data on out.
The static completion data is a shell script containing variable definitons
of the form {_COMPLETIONS_PREFIX}{COMMAND.PATH} for each dotted command path.
Args:
command: dict, The tree (nested dict) of command/group names.
out: stream, The output stream, sys.stdout if None.
"""
def ConvertPathToIdentifier(path):
return _COMPLETIONS_PREFIX + '__'.join(path).replace('-', '_')
def WalkCommandTree(command, prefix):
"""Visit each command and group in the CLI command tree.
Args:
command: dict, The tree (nested dict) of command/group names.
prefix: [str], The subcommand arg prefix.
"""
name = command.get(_LOOKUP_INTERNAL_NAME)
args = prefix + [name]
commands = command.get(cli_tree.LOOKUP_COMMANDS, [])
groups = command.get(cli_tree.LOOKUP_GROUPS, [])
names = []
for c in commands + groups:
names.append(c.get(_LOOKUP_INTERNAL_NAME, c))
if names:
flags = command.get(_LOOKUP_INTERNAL_FLAGS, [])
if prefix:
out.write('{identifier}=({args})\n'.format(
identifier=ConvertPathToIdentifier(args),
args=' '.join(names + flags)))
else:
out.write('{identifier}=({args})\n'.format(
identifier=ConvertPathToIdentifier(['-GCLOUD-WIDE-FLAGS-']),
args=' '.join(flags)))
out.write('{identifier}=({args})\n'.format(
identifier=ConvertPathToIdentifier(args),
args=' '.join(names)))
for c in commands:
name = c.get(_LOOKUP_INTERNAL_NAME, c)
flags = c.get(_LOOKUP_INTERNAL_FLAGS, [])
out.write('{identifier}=({args})\n'.format(
identifier=ConvertPathToIdentifier(args + [name]),
args=' '.join(flags)))
for g in groups:
WalkCommandTree(g, args)
if not out:
out = sys.stdout
WalkCommandTree(command, [])
class ListCommands(base.Command):
"""List all possible gcloud commands excluding flags."""
@staticmethod
def Args(parser):
parser.add_argument(
'--completions',
action='store_true',
help=("""\
Write the static TAB completion data on the standard output. The
data is a shell script containing variable definitons of the
form ```""" +
_COMPLETIONS_PREFIX +
'{COMMAND.PATH}``` for each dotted command path.')
)
parser.add_argument(
'--flags',
action='store_true',
help='Include the non-global flags for each command/group.')
parser.add_argument(
'--flag-values',
action='store_true',
help="""\
Include the non-global flags and flag values/types for each
command/group. Flags with fixed choice values will be listed as
--flag=choice1,..., and flags with typed values will be listed
as --flag=:type:.""")
parser.add_argument(
'--hidden',
action='store_true',
help='Include hidden commands and groups.')
parser.add_argument(
'--universe-compatible-commands',
hidden=True,
action='store_true',
help='Exclusively show universe compatible commands.')
parser.add_argument(
'restrict',
metavar='COMMAND/GROUP',
nargs='*',
help=('Restrict the listing to these dotted command paths. '
'For example: gcloud.alpha gcloud.beta.test'))
def Run(self, args):
if args.completions:
args.flags = True
args.flag_values = True
args.hidden = True
args.universe_compatible_commands = False
return walker_util.CommandTreeGenerator(
self._cli_power_users_only,
with_flags=args.flags,
with_flag_values=args.flag_values,
).Walk(args.hidden, args.universe_compatible_commands, args.restrict)
def Display(self, args, result):
if args.completions:
return DisplayCompletions(result)
return DisplayFlattenedCommandTree(result)