def GetFlagName(attribute_name, presentation_name, flag_name_overrides=None, prefixes=False): """Gets the flag name for a given attribute name. Returns a flag name for an attribute, adding prefixes as necessary or using overrides if an override map is provided. Args: attribute_name: str, the name of the attribute to base the flag name on. presentation_name: str, the anchor argument name of the resource the attribute belongs to (e.g. '--foo'). flag_name_overrides: {str: str}, a dict of attribute names to exact string of the flag name to use for the attribute. None if no overrides. prefixes: bool, whether to use the resource name as a prefix for the flag. Returns: (str) the name of the flag. """ flag_name_overrides = flag_name_overrides or {} if attribute_name in flag_name_overrides: return flag_name_overrides.get(attribute_name) if attribute_name == 'project': return '' # If the presentation spec's overall name is the same as the attribute, # treat this attibute like an "anchor" in a resource argument. if (util.NormalizeFormat(presentation_name) == util.NormalizeFormat(attribute_name)): return presentation_name if prefixes: return util.FlagNameFormat('-'.join([presentation_name, attribute_name])) return util.FlagNameFormat(attribute_name)
def AddConcept(self, name, concept_info, required=True): """Adds a concept handler for a given concept. Args: name: str, the name to be used for the presentation spec. concept_info: ConceptInfo, the object that holds dependencies of the concept. required: bool, True if the concept must be parseable, False if not. """ class LazyParse(object): def __init__(self, parse, arg_getter): self.parse = parse self.arg_getter = arg_getter def Parse(self): try: return self.parse(self.arg_getter()) except concepts.InitializationError as e: if required: raise ParseError(name, six.text_type(e)) return None setattr(self, name, LazyParse(concept_info.Parse, self.ParsedArgs)) self._all_concepts.append(concept_info) for _, arg_name in six.iteritems(concept_info.attribute_to_args_map): self._arg_name_lookup[util.NormalizeFormat( arg_name)] = concept_info
def _AddSpec(self, presentation_spec): """Adds a given presentation spec to the concept holder's spec registry. Args: presentation_spec: PresentationSpec, the spec to be added. Raises: ValueError: if two presentation specs have the same name, if two presentation specs are both positional, or if two args are going to overlap. """ # Check for duplicate spec names. for spec_name in self._specs: if self._ArgNameMatches(spec_name, presentation_spec.name): raise ValueError('Attempted to add two concepts with the same name: ' '[{}, {}]'.format(spec_name, presentation_spec.name)) if (util.IsPositional(spec_name) and util.IsPositional(presentation_spec.name)): raise ValueError('Attempted to add multiple concepts with positional ' 'arguments: [{}, {}]'.format(spec_name, presentation_spec.name)) # Also check for duplicate attribute names. for a, arg_name in presentation_spec.attribute_to_args_map.iteritems(): del a # Unused. name = util.NormalizeFormat(arg_name) if name in self._all_args: raise ValueError('Attempted to add a duplicate argument name: [{}]' .format(arg_name)) self._all_args.append(name) self._specs[presentation_spec.name] = presentation_spec
def _ArgNameMatches(self, name, other_name): """Checks if two argument names match in the namespace. RESOURCE_ARG and --resource-arg will match with each other, as well as exact matches. Args: name: the first argument name. other_name: the second argument name. Returns: (bool) True if the names match. """ if util.NormalizeFormat(name) == util.NormalizeFormat(other_name): return True return False
def AddToParser(self, parser): """Adds attribute args for all presentation specs to argparse. Args: parser: the parser for a Calliope command. """ parser.add_concepts(self._runtime_handler) for spec_name, spec in self._specs.iteritems(): self._runtime_handler.AddConcept(util.NormalizeFormat(spec_name), spec.concept_spec, spec.GetInfo()) spec.AddConceptToParser(parser)
def AddToParser(self, parser): """Adds attribute args for all presentation specs to argparse. Args: parser: the parser for a Calliope command. """ parser.add_concepts(self._runtime_handler) for spec_name, spec in six.iteritems(self._specs): concept_info = self.GetInfo(spec_name) concept_info.AddToParser(parser) self._runtime_handler.AddConcept(util.NormalizeFormat(spec_name), concept_info, required=spec.required)
def AddConcept(self, name, concept_info, required=True): """Adds a concept handler for a given concept. Args: name: str, the name to be used for the presentation spec. concept_info: ConceptInfo, the object that holds dependencies of the concept. required: bool, True if the concept must be parseable, False if not. Raises: RepeatedConceptName: If the given "name" has already been used with a concept. """ class LazyParse(object): """Class provided when accessing a concept to lazily parse from args.""" def __init__(self, parse, arg_getter): self.parse = parse self.arg_getter = arg_getter def Parse(self): try: return self.parse(self.arg_getter()) except concepts.InitializationError as e: if required: raise ParseError(name, six.text_type(e)) return None if hasattr(self, name): raise RepeatedConceptName(name) setattr(self, name, LazyParse(concept_info.Parse, self.ParsedArgs)) self._all_concepts.append({ 'name': name, 'concept_info': concept_info, 'required': required, }) for _, arg_name in six.iteritems(concept_info.attribute_to_args_map): self._arg_name_lookup[util.NormalizeFormat( arg_name)] = concept_info
def ArgNameToConceptInfo(self, arg_name): return self._arg_name_lookup.get(util.NormalizeFormat(arg_name))