130 lines
4.3 KiB
Python
130 lines
4.3 KiB
Python
# -*- coding: utf-8 -*- #
|
|
# Copyright 2018 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.
|
|
|
|
"""Coverage tree generator. Used for flag coverage kokoro presubmit."""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
from googlecloudsdk.calliope import walker
|
|
from googlecloudsdk.core.console import progress_tracker
|
|
from googlecloudsdk.core.resource import resource_printer
|
|
from googlecloudsdk.core.resource import resource_projector
|
|
|
|
|
|
def GenerateCoverageTree(cli, branch=None, restrict=None):
|
|
"""Generates and returns the static completion CLI tree.
|
|
|
|
Args:
|
|
cli: The CLI.
|
|
branch: The path of the CLI subtree to generate.
|
|
restrict: The paths in the tree that we are allowing the tree to walk under.
|
|
|
|
Returns:
|
|
Returns the serialized static completion CLI tree.
|
|
"""
|
|
with progress_tracker.ProgressTracker(
|
|
'Generating the flag coverage CLI tree.'):
|
|
return resource_projector.MakeSerializable(
|
|
CoverageTreeGenerator(cli, branch, restrict=restrict).Walk())
|
|
|
|
|
|
class CoverageCommandNode(dict):
|
|
"""Command/group info.
|
|
|
|
Attributes:
|
|
commands: {str:_Command}, The subcommands in a command group.
|
|
flags: [str], Command flag list. Global flags, available to all commands,
|
|
are in the root command flags list.
|
|
"""
|
|
|
|
def __init__(self, command, parent):
|
|
super(CoverageCommandNode, self).__init__()
|
|
# _parent is explicitly private so it won't appear in the output.
|
|
self._parent = parent
|
|
if parent is not None:
|
|
name = command.name.replace('_', '-')
|
|
parent[name] = self
|
|
|
|
args = command.ai
|
|
# Collect the command specific flags.
|
|
for arg in args.flag_args:
|
|
for name in arg.option_strings:
|
|
if arg.is_hidden:
|
|
continue
|
|
if not name.startswith('--'):
|
|
continue
|
|
if self.IsAncestorFlag(name):
|
|
continue
|
|
self[name] = arg.require_coverage_in_tests
|
|
|
|
def IsAncestorFlag(self, flag):
|
|
"""Determines if flag is provided by an ancestor command.
|
|
|
|
NOTE: This function is used to allow for global flags to be added in at the
|
|
top level but not in subgroups/commands
|
|
Args:
|
|
flag: str, The flag name (no leading '-').
|
|
|
|
Returns:
|
|
bool, True if flag provided by an ancestor command, false if not.
|
|
"""
|
|
command = self._parent
|
|
while command:
|
|
if flag in command:
|
|
return True
|
|
command = command._parent # pylint: disable=protected-access
|
|
return False
|
|
|
|
|
|
class CoverageTreeGenerator(walker.Walker):
|
|
"""Generates the gcloud static completion CLI tree."""
|
|
|
|
def __init__(self, cli=None, branch=None, restrict=None):
|
|
"""branch is the command path of the CLI subtree to generate."""
|
|
super(CoverageTreeGenerator, self).__init__(cli=cli, restrict=restrict)
|
|
self._branch = branch
|
|
|
|
def Visit(self, node, parent, is_group):
|
|
"""Visits each node in the CLI command tree to construct the external rep.
|
|
|
|
Args:
|
|
node: group/command CommandCommon info.
|
|
parent: The parent Visit() return value, None at the top level.
|
|
is_group: True if node is a command group.
|
|
|
|
Returns:
|
|
The subtree parent value, used here to construct an external rep node.
|
|
"""
|
|
return CoverageCommandNode(node, parent)
|
|
|
|
|
|
def OutputCoverageTree(cli, branch=None, out=None, restrict=None):
|
|
"""Lists the flag coverage CLI tree as a Python module file.
|
|
|
|
Args:
|
|
cli: The CLI.
|
|
branch: The path of the CLI subtree to generate.
|
|
out: The output stream to write to, sys.stdout by default.
|
|
restrict: The paths in the tree that we are allowing the tree to walk under.
|
|
|
|
Returns:
|
|
Returns the serialized coverage CLI tree.
|
|
"""
|
|
tree = GenerateCoverageTree(cli=cli, branch=branch, restrict=restrict)
|
|
resource_printer.Print(tree, print_format='json', out=out)
|
|
return tree
|