Contributing to COT

Please do contribute! We only have a few simple requirements for diffs and pull requests.

Follow coding guidelines

Logging level usage

COT uses logging levels (including the additional intermediate logging levels provided by the verboselogs package) as follows:

Level Usage guidelines Examples

Something is definitely wrong, but COT is able to proceed, at least for the moment. COT may raise an exception at some later point due to this issue.

If continuing is already known to be impossible, you should raise an exception now instead of logging an ERROR message.

  • OVF descriptor is not following the specification.
  • User has provided invalid input, but can retry.
  • Expected data is missing.
  • Internal logic error in COT that should never be encountered.

Something potentially wrong, or at least risky, happened that the user should be informed of.

This includes cases where, due to insufficient information provided by the user, COT had to make an uncertain choice on its own (or was unable to make such a decision but is continuing nonetheless).

  • COT would have prompted the user to provide input or confirm a risky operation, but has been instructed to run non-interactively.
  • COT is having to guess whether a given disk drive should be SCSI or IDE as the user didn't specify which when instructing COT to add the drive.
  • User-provided information was unused, such as providing the device type to set for a device that doesn't exist.
  • User has instructed COT to configure hardware settings that appear to be outside the supported range for the given platform.

Something noteworthy happened that is not necessarily a problem, but deserves the user's attention.

This is the lowest logging level enabled by default, so messages generated at and above this level should be succinct and meaningful to all users.

  • COT does not recognize the virtual platform described by a given OVF and so will be treating it generically.
  • COT is attempting to install a needed helper application.
  • COT is having to create parts of the OVF descriptor from scratch.
  • COT is replacing a file or disk that was previously included in this OVF with a new one.
INFO Status updates about normal operation of the software.
  • COT has successfully parsed an OVF or OVA and is ready to operate on it.
  • COT is beginning to write the updated OVF/OVA to disk.
VERBOSE Detailed information of interest to an expert or very curious user.
  • Individual task steps of editing an OVF.
  • COT's reasoning for making high-level decisions.
DEBUG Highly detailed information, probably only useful to a developer familiar with the code.
  • Information about temporary files and other internal state of COT itself.
  • Individual operations within a complex task.
SPAM Extremely detailed or repetitive info that even a developer will rarely want to see.
  • Data dumps of XML elements and other data structures.
  • Status updates on tasks that typically happen many times in a single COT run.

Coding style

We try to keep COT's code base compliant with Python coding standards including PEP 8 and PEP 257. We use the flake8 and Pylint tools and their extension packages to verify this as part of our test automation. To run coding style analysis independently of the other test automation, you can run tox -e flake8,pylint, or you can install these tools and run them directly:

cot/$ sudo pip install --upgrade flake8
cot/$ sudo pip install --upgrade pydocstyle
cot/$ sudo pip install --upgrade flake8-docstrings
cot/$ sudo pip install --upgrade pep8-naming
cot/$ sudo pip install --upgrade mccabe
cot/$ flake8
./COT/ovf/ C901 'OVFItem.value_replace_wildcards' is too complex (11)
./COT/ovf/ C901 'OVFItem.generate_items' is too complex (11)
./COT/ovf/ C901 'OVF.validate_hardware' is too complex (14)
cot/$ sudo pip install --upgrade pylint
cot/$ pylint COT
************* Module COT.ovf.item
E:331,24: Instance of 'list' has no 'split' member (no-member)
R:334,16: Redefinition of value type from list to tuple (redefined-variable-type)
R:603, 4: Too many branches (13/12) (too-many-branches)
************* Module COT.ovf.ovf
C:  1, 0: Too many lines in module (2646/2600) (too-many-lines)
R:177, 0: Too many public methods (76/74) (too-many-public-methods)

Fix any errors and warnings these tools report, and run again until no errors are reported.

CLI consistency

When adding or modifying CLI, keep the following guidelines in mind:

  • All subcommands must support -h/--help. Never redefine -h to mean something other than "get help".
  • All commands that modify files must define -o/--output to specify a new file to create instead of overwriting any input file. If and only if the command does not modify the input file, you may use -o to mean something else (e.g., cot deploy ... has -o/--ovftool-args).
  • Best effort: use consistent argument names and short argument names unless there's an unavoidable conflict. Examples:
    • cot add-file and cot add-disk abbreviate --file-id as -f, but cot remove-file abbreviates it as -i because it uses -f to mean --file-path. In retrospect, using -p for --file-path would have allowed COT to be more self-consistenct.
    • cot edit-hardware uses -p/--profiles to specify one or more configuration profiles to operate on. cot deploy esxi uses -c/--configuration to specify the configuration profile to deploy. In this case, this is somewhat unavoidable as cot edit-hardware uses -c to mean --cpus (no reasonable alternative) and cot deploy esxi uses -p to mean --password (likewise).
  • In cases where short argument names unavoidably differ between commands, support the same set of long names if at all possible. For example, cot edit-hardware and cot deploy esxi should both support both --profile(s) and --configuration(s) as synonymous long names that can be used interchangeably to specify a configuration profile.

Add automated unit tests

Whether adding new functionality or fixing a bug, please add appropriate unit test case(s) under COT/tests/ or COT/<sub-package>/tests/ (as appropriate) to cover your changes. Your changes must pass all existing and new automated test cases before your code will be accepted.

You can run the COT automated tests under a single Python version by running python ./ test.

For full testing under all supported versions as well as verifying code coverage for your tests, you should install tox (pip install tox) and coverage (pip install coverage) then run tox from the COT directory:

cot/$ tox
py27 runtests: commands[0] | coverage run --append test --quiet
py33 runtests: commands[0] | coverage run --append test --quiet
py34 runtests: commands[0] | coverage run --append test --quiet
py35 runtests: commands[0] | coverage run --append test --quiet
py36 runtests: commands[0] | coverage run --append test --quiet
pypy runtests: commands[0] | coverage run --append test --quiet
flake8 runtests: commands[0] | flake8
pylint runtests: commands[0] | pylint COT
docs runtests: commands[0] | sphinx-build -W -b html -d ...
stats runtests: commands[0] | coverage combine
stats runtests: commands[1] | coverage report -i
Name                                 Stmts   Miss Branch BrPart  Cover
COT/                          5      0      0      0   100%
COT/                        168      3     66      3    97%
COT/                         45      0     12      0   100%
COT/                             254     15     95      9    93%
COT/                 124      2     44      1    98%
COT/                          154      6     62      6    94%
COT/                     196      0     68      1    99%
COT/disks/                   23      0     10      0   100%
COT/disks/                       56      1     20      1    97%
COT/                  166      4      4      0    98%
COT/                       26      0      4      0   100%
COT/                        121      3     54      1    98%
TOTAL                                 5122    114   1908    105    97%
stats runtests: commands[2] | coverage html -i
_______________ summary _______________
  setup: commands succeeded
  py27: commands succeeded
  py33: commands succeeded
  py34: commands succeeded
  py35: commands succeeded
  py36: commands succeeded
  pypy: commands succeeded
  flake8: commands succeeded
  pylint: commands succeeded
  docs: commands succeeded
  stats: commands succeeded
  congratulations :)

After running tox you can check the code coverage details by opening htmlcov/index.html in a web browser.

Update documentation

If you add or change any COT CLI or APIs, or add or remove any external dependencies, please update the relevant documentation.

Add yourself as a contributor

If you haven't contributed to COT previously, be sure to add yourself as a contributor in the COPYRIGHT.txt file.

Open a pull request

COT follows Vincent Driessen's A successful Git branching model. As such, please submit feature enhancement and non-critical bugfix requests to merge into the develop branch rather than master.