197 lines
6.4 KiB
Python
197 lines
6.4 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.
|
|
"""Abstract base class for concepts.
|
|
|
|
This base class cannot be used as a concept on its own but must be subclassed,
|
|
and the methods Attribute(), GetPresentationName(), and Parse() must be
|
|
implemented.
|
|
|
|
Example usage:
|
|
|
|
class IntConcept(Concept):
|
|
|
|
def __init__(self, **kwargs):
|
|
super(IntConcept, self).__init__(name='int', **kwargs)
|
|
|
|
def Attribute(self):
|
|
return Attribute(concept=self,
|
|
fallthroughs=self.fallthroughs,
|
|
help=self.BuildHelpText(),
|
|
required=self.required,
|
|
hidden=self.hidden,
|
|
completer=self.completer,
|
|
metavar=self.metavar)
|
|
|
|
def GetPresentationName(self):
|
|
return googlecloudsdk.command_lib.concepts.names.FlagNameFormat(
|
|
self.name)
|
|
|
|
def BuildHelpText(self):
|
|
super(IntConcept, self).BuildHelpText() + ' Must be an int.'
|
|
|
|
def Parse(self, dependencies):
|
|
try:
|
|
return int(dependencies.value)
|
|
except ValueError:
|
|
raise googlecloudsdk.command_lib.concepts.exceptions.Error(
|
|
'Could not parse int concept; you provided [{}]'
|
|
.format(dependencies.value))
|
|
|
|
* Note for Concept Implementers *
|
|
When implementing a new concept that produces a single argument, you can
|
|
subclass googlecloudsdk.command_lib.concepts.all_concepts.SimpleArg in order to
|
|
take advantage of general functionality, such as creating a simple presentation
|
|
name based on whether concept.positional is True, determining whether the
|
|
produced attribute is required, raising an exception if no value is found and
|
|
the concept is required, and storing fallthroughs.
|
|
"""
|
|
|
|
from __future__ import absolute_import
|
|
from __future__ import division
|
|
from __future__ import unicode_literals
|
|
|
|
import abc
|
|
import six
|
|
|
|
|
|
class Concept(six.with_metaclass(abc.ABCMeta, object)):
|
|
"""Abstract base class for concept args.
|
|
|
|
Attributes:
|
|
name: str, the name of the concept. Used to determine
|
|
the argument or group name of the concept.
|
|
key: str, the name by which the parsed concept is stored in the dependency
|
|
view. If not given, is the same as the concept's name. Generally,
|
|
this should only be set and used by containing concepts when parsing
|
|
from a DependencyView object. End users of concepts do not need to
|
|
use it.
|
|
help_text: str, the help text to be displayed for this concept.
|
|
required: bool, whether the concept must be provided by the end user. If
|
|
False, it's acceptable to have an empty result; otherwise, an empty
|
|
result will raise an error.
|
|
hidden: bool, whether the associated argument or group should be hidden.
|
|
"""
|
|
|
|
def __init__(self, name, key=None, help_text='', required=False,
|
|
hidden=False):
|
|
self.name = name
|
|
self.help_text = help_text
|
|
self.required = required
|
|
self.hidden = hidden
|
|
self.key = key or self.name
|
|
|
|
@abc.abstractmethod
|
|
def Attribute(self):
|
|
"""Returns an Attribute object representing the attributes.
|
|
|
|
Must be defined in subclasses.
|
|
|
|
Returns:
|
|
Attribute | AttributeGroup, the attribute or group.
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
@abc.abstractmethod
|
|
def GetPresentationName(self):
|
|
"""Returns the main name for the concept."""
|
|
raise NotImplementedError
|
|
|
|
def BuildHelpText(self):
|
|
"""Builds and returns the help text.
|
|
|
|
Returns:
|
|
str, the help text for the concept.
|
|
"""
|
|
return self.help_text
|
|
|
|
def Marshal(self):
|
|
"""Returns the list of concepts that this concept marshals."""
|
|
return None
|
|
|
|
@abc.abstractmethod
|
|
def Parse(self, dependencies):
|
|
"""Parses the concept.
|
|
|
|
Args:
|
|
dependencies: a DependenciesView object.
|
|
|
|
Returns:
|
|
the parsed concept.
|
|
|
|
Raises:
|
|
googlecloudsdk.command_lib.concepts.exceptions.Error, if parsing fails.
|
|
"""
|
|
raise NotImplementedError
|
|
|
|
@abc.abstractmethod
|
|
def IsArgRequired(self):
|
|
"""Returns whether this concept is required to be specified by argparse."""
|
|
return False
|
|
|
|
def MakeArgKwargs(self):
|
|
"""Returns argparse kwargs shared between all concept types."""
|
|
return {
|
|
'help': self.BuildHelpText(),
|
|
'required': self.IsArgRequired(),
|
|
'hidden': self.hidden,
|
|
}
|
|
|
|
|
|
class Attribute(object):
|
|
"""An attribute that gets transformed to an argument.
|
|
|
|
Attributes:
|
|
concept: Concept, the underlying concept.
|
|
key: str, the name by which the Attribute is looked up in the dependency
|
|
view.
|
|
fallthroughs: [deps.Fallthrough], the list of fallthroughs for the concept.
|
|
kwargs: {str: any}, other metadata describing the attribute. Available
|
|
keys include: required (bool), hidden (bool), help (str), completer,
|
|
default, nargs. **Note: This is currently used essentially as a
|
|
passthrough to the argparse library.
|
|
"""
|
|
|
|
def __init__(self, concept=None, fallthroughs=None, **kwargs):
|
|
self.concept = concept
|
|
self.fallthroughs = fallthroughs or []
|
|
self.kwargs = kwargs
|
|
|
|
@property
|
|
def arg_name(self):
|
|
"""A string property representing the final argument name."""
|
|
return self.concept.GetPresentationName()
|
|
|
|
|
|
class AttributeGroup(object):
|
|
"""Represents an object that gets transformed to an argument group.
|
|
|
|
Attributes:
|
|
concept: Concept, the underlying concept.
|
|
key: str, the name by which the Attribute is looked up in the dependency
|
|
view.
|
|
attributes: [Attribute | AttributeGroup], the list of attributes or
|
|
attribute groups contained in this attribute group.
|
|
kwargs: {str: any}, other metadata describing the attribute. Available
|
|
keys include: required (bool), mutex (bool), hidden (bool), help (str).
|
|
**Note: This is currently used essentially as a passthrough to the
|
|
argparse library.
|
|
"""
|
|
|
|
def __init__(self, concept=None, attributes=None, **kwargs):
|
|
self.concept = concept
|
|
self.key = concept.key
|
|
self.attributes = attributes or []
|
|
self.kwargs = kwargs
|