Skip to content

Commit

Permalink
Merge branch 'feature/alias' into develop - fixes #21
Browse files Browse the repository at this point in the history
  • Loading branch information
glennmatthews committed Jun 5, 2016
2 parents 6dbaeff + 5e0b601 commit bdfcae0
Show file tree
Hide file tree
Showing 18 changed files with 185 additions and 200 deletions.
9 changes: 9 additions & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ This project adheres to `Semantic Versioning`_.
and ``--scsi-subtypes`` in ``cot edit-hardware``.
- COT now recognizes the Cisco IOS XRv 9000 platform identifier
``com.cisco.ios-xrv9000``.
- `#21`_ - subcommand aliases (Python 3.x only):

- ``cot edit-product`` aliases: ``cot set-product``, ``cot set-version``
- ``cot edit-properties`` aliases: ``cot set-properties``,
``cot edit-environment``, ``cot set-environment``
- ``cot info`` alias: ``cot describe``
- ``cot inject-config`` alias: ``cot add-bootstrap``
- ``cot remove-file`` alias: ``cot delete-file``

**Changed**

Expand Down Expand Up @@ -357,6 +365,7 @@ Initial public release.
.. _#17: https://github.com/glennmatthews/cot/issues/17
.. _#19: https://github.com/glennmatthews/cot/issues/19
.. _#20: https://github.com/glennmatthews/cot/issues/20
.. _#21: https://github.com/glennmatthews/cot/issues/21
.. _#24: https://github.com/glennmatthews/cot/issues/24
.. _#26: https://github.com/glennmatthews/cot/issues/26
.. _#28: https://github.com/glennmatthews/cot/issues/28
Expand Down
21 changes: 7 additions & 14 deletions COT/add_disk.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# add_disk.py - Implements "cot add-disk" command
#
# August 2013, Glenn F. Matthews
# Copyright (c) 2013-2015 the COT project developers.
# Copyright (c) 2013-2016 the COT project developers.
# See the COPYRIGHT.txt file at the top-level directory of this distribution
# and at https://github.com/glennmatthews/cot/blob/master/COPYRIGHT.txt.
#
Expand Down Expand Up @@ -167,17 +167,12 @@ def run(self):
diskname=self.diskname,
description=self.description)

def create_subparser(self, parent, storage):
"""Add subparser for the CLI of this submodule.
:param object parent: Subparser grouping object returned by
:meth:`ArgumentParser.add_subparsers`
:param dict storage: Dict of { 'label': subparser } to be updated with
subparser(s) created, if any.
"""
p = parent.add_parser(
'add-disk', add_help=False,
def create_subparser(self):
"""Create 'add-disk' CLI subparser."""
p = self.UI.add_subparser(
'add-disk',
aliases=['add-drive'],
add_help=False,
usage=self.UI.fill_usage("add-disk", [
"DISK_IMAGE PACKAGE [-o OUTPUT] [-f FILE_ID] \
[-t {harddisk,cdrom}] [-c {ide,scsi}] [-s SUBTYPE] [-a ADDRESS] \
Expand Down Expand Up @@ -240,8 +235,6 @@ def create_subparser(self, parent, storage):
help="""OVF descriptor or OVA file to edit""")
p.set_defaults(instance=self)

storage['add-disk'] = p


def add_disk_worker(vm,
UI,
Expand Down
17 changes: 4 additions & 13 deletions COT/add_file.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# add_file.py - Implements "cot add-file" command
#
# October 2013, Glenn F. Matthews
# Copyright (c) 2013-2015 the COT project developers.
# Copyright (c) 2013-2016 the COT project developers.
# See the COPYRIGHT.txt file at the top-level directory of this distribution
# and at https://github.com/glennmatthews/cot/blob/master/COPYRIGHT.txt.
#
Expand Down Expand Up @@ -101,16 +101,9 @@ def run(self):

vm.add_file(self.file, self.file_id, file)

def create_subparser(self, parent, storage):
"""Add subparser for the CLI of this submodule.
:param object parent: Subparser grouping object returned by
:meth:`ArgumentParser.add_subparsers`
:param dict storage: Dict of { 'label': subparser } to be updated with
subparser(s) created, if any.
"""
p = parent.add_parser(
def create_subparser(self):
"""Create 'add-file' CLI subparser."""
p = self.UI.add_subparser(
'add-file',
usage=self.UI.fill_usage("add-file", [
"FILE PACKAGE [-o OUTPUT] [-f FILE_ID]",
Expand All @@ -132,5 +125,3 @@ def create_subparser(self, parent, storage):
p.add_argument('PACKAGE',
help="""Package, OVF descriptor or OVA file to edit""")
p.set_defaults(instance=self)

storage['add-file'] = p
31 changes: 30 additions & 1 deletion COT/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,36 @@ def create_subparsers(self):
instance = klass(self)
# the subparser stores a reference to the instance (args.instance)
# so we don't need to persist it here...
instance.create_subparser(self.subparsers, self.subparser_lookup)
instance.create_subparser()

def add_subparser(self, title,
parent=None, aliases=None, lookup_prefix="",
**kwargs):
"""Create a subparser under the specified parent.
:param str title: Canonical keyword for this subparser
:param object parent: Subparser grouping object returned by
:meth:`ArgumentParser.add_subparsers`
:param list aliases: Aliases for ``title``. Only used
in Python 3.x.
:param str lookup_prefix: String to prepend to ``title`` and
each alias in ``aliases`` for lookup purposes.
"""
# Subparser aliases are only supported by argparse in Python 3.2+
if sys.hexversion >= 0x03020000 and aliases:
kwargs['aliases'] = aliases
else:
aliases = None

if parent is None:
parent = self.subparsers

p = parent.add_parser(title, **kwargs)
self.subparser_lookup[lookup_prefix + title] = p
if aliases:
for alias in aliases:
self.subparser_lookup[lookup_prefix + alias] = p
return p

def parse_args(self, argv):
"""Parse the given CLI arguments into a namespace object.
Expand Down
35 changes: 15 additions & 20 deletions COT/deploy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# deploy.py - Implements "cot deploy" command
#
# June 2014, Kevin A. Keim
# Copyright (c) 2014-2015 the COT project developers.
# Copyright (c) 2014-2016 the COT project developers.
# See the COPYRIGHT.txt file at the top-level directory of this distribution
#
# This file is part of the Common OVF Tool (COT) project.
Expand Down Expand Up @@ -199,8 +199,8 @@ def __init__(self, UI):
"""Subparser grouping for hypervisor-specific sub-subparsers.
Subclasses should generally have their :func:`create_subparser`
implementations create their sub-subparsers under :attr:`subparsers`
and NOT under :attr:`parent`.
implementations create their sub-subparsers with
``parent=``:attr:`subparsers`.
"""

@property
Expand Down Expand Up @@ -333,27 +333,22 @@ def run(self):
.format(self.package, self.configuration, serial_count,
len(self.serial_connection)))

def create_subparser(self, parent, storage):
"""Add subparser for the CLI of this submodule.
def create_subparser(self):
"""Create 'deploy' CLI subparser if it doesn't already exist.
.. note::
Unlike most submodules, this one has subparsers of its own -
``'cot deploy PACKAGE <hypervisor>'`` so subclasses of this module
should call ``super().create_subparser(parent, storage)`` (to create
the main 'deploy' subparser if it doesn't already exist) then call
``self.subparsers.add_parser()`` to add their own sub-subparser.
:param object parent: Subparser grouping object returned by
:func:`ArgumentParser.add_subparsers`
:param dict storage: Dict of { 'label': subparser } to be updated with
subparser(s) created, if any.
should call ``super().create_subparser()`` (to create the main
'deploy' subparser if it doesn't already exist) then call
``self.UI.add_parser(..., parent=self.subparsers, ...)`` to add
their own sub-subparser.
"""
import argparse

if storage.get('deploy', None) is None:
if self.UI.subparser_lookup.get('deploy', None) is None:
# Create 'cot deploy' parser
p = parent.add_parser(
p = self.UI.add_subparser(
'deploy',
usage=self.UI.fill_usage("deploy", [
"PACKAGE esxi ...",
Expand All @@ -372,13 +367,13 @@ def create_subparser(self, parent, storage):
title="hypervisors")

p.set_defaults(instance=self)
storage['deploy'] = p
else:
# Unfortunately argparse doesn't readily expose the subparsers of
# an existing parser. The below should be considered experimental!
self.subparsers = next(action for
action in storage['deploy']._actions if
type(action).name == '_SubParsersAction')
self.subparsers = next(
action for
action in self.UI.subparser_lookup['deploy']._actions if
type(action).name == '_SubParsersAction')

# Create a generic parser with arguments to be shared by all
self.generic_parser = argparse.ArgumentParser(add_help=False)
Expand Down
26 changes: 11 additions & 15 deletions COT/deploy_esxi.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# deploy_esxi.py - Implements "cot deploy ... esxi" command
#
# August 2015, Glenn F. Matthews
# Copyright (c) 2014-2015 the COT project developers.
# Copyright (c) 2014-2016 the COT project developers.
# See the COPYRIGHT.txt file at the top-level directory of this distribution
#
# This file is part of the Common OVF Tool (COT) project.
Expand Down Expand Up @@ -396,25 +396,22 @@ def fixup_serial_ports(self, serial_count):

logger.info("Done with serial port fixup")

def create_subparser(self, parent, storage):
def create_subparser(self):
"""Add subparser for the CLI of this submodule.
This will create the shared :attr:`~COTDeploy.parser` under
:attr:`parent`, then create our own sub-subparser under
:attr:`~COTDeploy.subparsers`.
:param object parent: Subparser grouping object returned by
:func:`ArgumentParser.add_subparsers`
:param dict storage: Dict of { 'label': subparser } to be updated with
subparser(s) created, if any.
This will create the shared :attr:`~COTDeploy.parser`, then
create our own sub-subparser under :attr:`~COTDeploy.subparsers`.
"""
super(COTDeployESXi, self).create_subparser(parent, storage)
super(COTDeployESXi, self).create_subparser()

import argparse
# Create 'cot deploy ... esxi' parser
p = self.subparsers.add_parser(
'esxi', parents=[self.generic_parser],
p = self.UI.add_subparser(
'esxi',
aliases=['vcenter', 'vmware', 'vsphere'],
parent=self.subparsers,
lookup_prefix="deploy-",
parents=[self.generic_parser],
usage=self.UI.fill_usage("deploy PACKAGE esxi", [
"LOCATOR [-u USERNAME] [-p PASSWORD] [-c CONFIGURATION] "
"[-n VM_NAME] [-P] [-N OVF1=HOST1 [-N OVF2=HOST2 ...]] "
Expand Down Expand Up @@ -463,4 +460,3 @@ def create_subparser(self, parent, storage):
'(deploy via vCenter server)')

p.set_defaults(instance=self)
storage['deploy-esxi'] = p
20 changes: 6 additions & 14 deletions COT/edit_hardware.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# edit_hardware.py - Implements "edit-hardware" sub-command
#
# September 2013, Glenn F. Matthews
# Copyright (c) 2013-2015 the COT project developers.
# Copyright (c) 2013-2016 the COT project developers.
# See the COPYRIGHT.txt file at the top-level directory of this distribution
# and at https://github.com/glennmatthews/cot/blob/master/COPYRIGHT.txt.
#
Expand Down Expand Up @@ -433,20 +433,14 @@ def run(self):
if self.ide_subtypes is not None:
vm.set_ide_subtypes(self.ide_subtypes, self.profiles)

def create_subparser(self, parent, storage):
"""Add subparser for the CLI of this submodule.
:param object parent: Subparser grouping object returned by
:meth:`ArgumentParser.add_subparsers`
:param dict storage: Dict of { 'label': subparser } to be updated with
subparser(s) created, if any.
"""
def create_subparser(self):
"""Create 'edit-hardware' CLI subparser."""
wrapper = textwrap.TextWrapper(width=self.UI.terminal_width - 1,
initial_indent=' ',
subsequent_indent=' ')
p = parent.add_parser(
'edit-hardware', add_help=False,
p = self.UI.add_subparser(
'edit-hardware',
add_help=False,
formatter_class=argparse.RawDescriptionHelpFormatter,
usage=self.UI.fill_usage("edit-hardware", [
"PACKAGE [-o OUTPUT] -v TYPE [TYPE2 ...]",
Expand Down Expand Up @@ -566,8 +560,6 @@ def create_subparser(self, parent, storage):
help="OVF descriptor or OVA file to edit")
p.set_defaults(instance=self)

storage['edit-hardware'] = p

def expand_list_wildcard(self, name_list, length):
"""Expand a list containing a wildcard to the desired length.
Expand Down
18 changes: 5 additions & 13 deletions COT/edit_product.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
# edit_product.py - Implements "edit-product" sub-command
#
# August 2013, Glenn F. Matthews
# Copyright (c) 2013-2015 the COT project developers.
# Copyright (c) 2013-2016 the COT project developers.
# See the COPYRIGHT.txt file at the top-level directory of this distribution
# and at https://github.com/glennmatthews/cot/blob/master/COPYRIGHT.txt.
#
Expand Down Expand Up @@ -128,17 +128,11 @@ def run(self):
self.application_url))
self.vm.application_url = self.application_url

def create_subparser(self, parent, storage):
"""Add subparser for the CLI of this submodule.
:param object parent: Subparser grouping object returned by
:meth:`ArgumentParser.add_subparsers`
:param dict storage: Dict of { 'label': subparser } to be updated with
subparser(s) created, if any.
"""
p = parent.add_parser(
def create_subparser(self):
"""Create 'edit-product' CLI subparser."""
p = self.UI.add_subparser(
'edit-product',
aliases=['set-product', 'set-version'],
help="""Edit product info in an OVF""",
usage=self.UI.fill_usage("edit-product", [
"PACKAGE [-o OUTPUT] [-p PRODUCT] [-n VENDOR] \
Expand Down Expand Up @@ -171,5 +165,3 @@ def create_subparser(self, parent, storage):
p.add_argument('PACKAGE',
help="OVF descriptor or OVA file to edit")
p.set_defaults(instance=self)

storage['edit-product'] = p
19 changes: 6 additions & 13 deletions COT/edit_properties.py
Original file line number Diff line number Diff line change
Expand Up @@ -207,17 +207,12 @@ def edit_properties_interactive(self):
continue
continue

def create_subparser(self, parent, storage):
"""Add subparser for the CLI of this submodule.
:param object parent: Subparser grouping object returned by
:meth:`ArgumentParser.add_subparsers`
:param dict storage: Dict of { 'label': subparser } to be updated with
subparser(s) created, if any.
"""
p = parent.add_parser(
'edit-properties', add_help=False,
def create_subparser(self):
"""Create 'edit-properties' CLI subparser."""
p = self.UI.add_subparser(
'edit-properties',
aliases=['set-properties', 'edit-environment', 'set-environment'],
add_help=False,
help="""Edit environment properties of an OVF""",
usage=self.UI.fill_usage("edit-properties", [
"PACKAGE [-p KEY1=VALUE1 [KEY2=VALUE2 ...]] [-c CONFIG_FILE] "
Expand Down Expand Up @@ -258,5 +253,3 @@ def create_subparser(self, parent, storage):
"arbitrary URI may be specified.")

p.set_defaults(instance=self)

storage['edit-properties'] = p
Loading

0 comments on commit bdfcae0

Please sign in to comment.