=========================== Taskotron Development Guide =========================== So, you're interested in getting helping out with libtaskotron? Great, this will help get you started on that. General Information =================== Libtaskotron is written mostly in `Python `_. Source Code ----------- The source code for libtaskotron is in a git repository on bitbucket: https://bitbucket.org/fedoraqa/libtaskotron If you submit patches, please use the process of :ref:`submitting-code`. .. _taskotron-bugs: Bugs, Issues and Tasks ---------------------- We use `Phabricator `_ to track issues and facilitate code reviews for several projects related to libtaskotron and Fedora QA. Our phabricator instance can be found at https://phab.qadevel.cloud.fedoraproject.org/ .. _running-tests: Running unit and functional tests --------------------------------- We place a high value on having decent test coverage for the libtaskotron code. In general, tests are written using `pytest ` and are broken up into two types: * **Unit Tests** test the core logic of code. They do not touch the filesystem or interact with any network resources. The unit tests should run very quickly * **Functional Tests** are a set of more comprehensive tests which are allowed to touch the filesystem and/or interact with networked resources. Functional tests are often much slower than unit tests but they offer coverage which is not present in the unit tests. To run the unit tests:: py.test testing/ To run the functional and unit tests:: py.test -F testing/ Support tools ------------- There are several tools that, while not required, make the process of developing for libtaskotron significantly easier. .. _installing-arcanist: Arcanist ^^^^^^^^ `Arcanist `_ is a command line interface to Phabricator which can be used to submit code reviews, download/apply code under review among other useful functions. As Arcanist is an interface to Phabricator, we **strongly recommend** that you install it using our packages instead of from the upstream git repos (as described in upstream documentation). That way, there is no question that the Arcanist version used locally is compatible with our Phabricator instance. To add our yum repository containing Phabricator related packages, run:: sudo curl http://repos.fedorapeople.org/repos/tflink/phabricator/fedora-phabricator.repo -o /etc/yum.repos.d/fedora-phabricator.repo Once the repository has been configured, install Arcanist using:: sudo yum install arcanist Arcanist is written in PHP and installing it will pull in several PHP packages as dependencies. .. _installing-gitflow: gitflow ^^^^^^^ The `gitflow plugin for git `_ is another useful, but not required tool that is available in the Fedora repositories. To install the gitflow plugin, run:: sudo yum install gitflow .. _submitting-code: Submitting code --------------- Libtaskotron follows the `gitflow `_ branching model and with the exception of hotfixes, all changes made should be against the ``develop`` branch. While not required, using the `gitflow plugin for git `_ is recommended as it makes the process significantly easier. See :ref:`installing-gitflow` for instructions on installing gitflow on Fedora. Start a new feature ^^^^^^^^^^^^^^^^^^^ To start work on a new feature, use:: git flow feature start TXXX-short-description Where ``TXXX`` is the issue number in Phabricator and ``short-description`` is a short, human understandable description of the change contained in this branch. In general, short reviews are better than long reviews. If you can, please break up features into chunks that are smaller and easier to manage. Submitting code for review ^^^^^^^^^^^^^^^^^^^^^^^^^^ .. note:: Make sure to run all unit and functional tests before submitting code for review. Any code that causes test failure will receive requests to fix the offending code or will be rejected. See :ref:`running-tests` for information on running unit and functional tests. Code reviews are done through Phabricator, not pull requests. While it is possible to submit code for review through the web interface, :ref:`installing-arcanist` is recommended. You do not need to push code anywhere public before submitting a review. Unless there is a good reason to do so (and there are very few), pushing a feature branch to origin is frowned on as it makes repository maintenance more difficult for no real benefit. To submit code for review, make sure that your code has been updated with respect to ``origin/develop`` and run the following from your checked-out feature branch:: arc diff develop The first time that you use Arcanist, it will ask for an API key which can be retrieved from a link contained in that prompt. Arcanist will create a new code review on our Phabricator instance and prompt you for information about the testing which has been done, a description of the code under review and people to whom the review should be assigned. If you're not clear on who should review your code, leave the ``reviewers`` section blank and someone will either review your code or assign the review task to someone who will. Updating code reviews ^^^^^^^^^^^^^^^^^^^^^ There will often be requests for changes to the code submitted for review. Once the requested changes have been made in your feature branch, commit them and make sure that your branch is still up to date with respect to ``origin/develop``. To update the existing review, use:: arc diff develop --update DXXX Where ``DXXX`` is the Differential ID assigned to your review when it was originally created. Pushing code ^^^^^^^^^^^^ .. note:: Changes to git are very difficult to undo or cleanup once they have been pushed to a central repository. If you are not comfortable going through the process listed here, please ask for help. If you run into any problems before pushing code to origin, please ask for help **before** pushing. Once the review has been accepted, the code needs to be merged into ``develop`` and pushed to ``origin``. Make sure that your local ``develop`` branch is up-to-date with ``origin/develop`` before starting the merge process, else messy commits and merges may ensue. Once ``develop`` is up-to-date, the basic workflow to use is:: git checkout feature/TXXX-some-feature git rebase develop To merge the code into develop, use one of two commands. If the feature can be reasonably expressed in one commit (most features), use:: git flow feature finish --squash TXXX-some-feature Else, if the Feature is larger and should cover multiple commits (less common), use:: git flow feature finish TXXX-some-feature After merging the code, please inspect log messages in case they need to be shortened (Phabricator likes to make long commit messages). Groups of commits should at least have a short description of their content and a link to the revision in differential. Once the feature is ready, push to origin:: git push origin develop Reviewing Code -------------- To review code, use `Phabricator's web interface `_ to submit comments, request changes or accept reviews. If you want to look at the code under review locally to run tests or test suggestions prior to posting them, use Arcanist to apply the review code. Make sure that your local repo is at the same base revision as the code under review (usually origin/develop) and run the following command:: arc patch DXXX Where ``DXXX`` is the review id that you're interested in. Arcanist will grab the code under review and apply it to a local branch named ``arcpatch-DXXX``. You can then look at the code locally or make modifications. Writing directives ================== **TODO** Write documentation on writing directives for libtaskotron Documentation ============= The documentation for libtaskotron is made up of several sources which are combined together into a single document using `Sphinx `_. Most of the libtaskotron docs are written in `reStructuredText `_ (reST) and unless otherwise mentioned, follow the `Python documentation style guide `_ Building documentation ---------------------- The documentation is easy to build once deps are installed:: yum install python-sphinx To actually build the documentation:: cd docs/ make html Docstrings ---------- Docstrings should be formatted using a reST-like format which Sphinx's autodoc extension can easily render into HTML. Sphinx has several built-in info fields which should be used to document function/method arguments and return data. The following is an excerpt from `the Sphinx documentation `_ Inside Python object description directives, reST field lists with these fields are recognized and formatted nicely: * ``param``, ``parameter``, ``arg``, ``argument``, ``key``, ``keyword``: Description of a parameter. * ``type``: Type of a parameter. * ``raises``, ``raise``, ``except``, ``exception``: That (and when) a specific exception is raised. * ``var``, ``ivar``, ``cvar``: Description of a variable. * ``returns``, ``return``: Description of the return value. * ``rtype``: Return type. The field names must consist of one of these keywords and an argument (except for ``returns`` and ``rtype``, which do not need an argument). This is best explained by an example:: .. py:function:: send_message(sender, recipient, message_body, [priority=1]) Send a message to a recipient :param str sender: The person sending the message :param str recipient: The recipient of the message :param str message_body: The body of the message :param priority: The priority of the message, can be a number 1-5 :type priority: integer or None :return: the message id :rtype: int :raises ValueError: if the message_body exceeds 160 characters :raises TypeError: if the message_body is not a basestring This will render like this: .. py:function:: send_message(sender, recipient, message_body, [priority=1]) :noindex: Send a message to a recipient :param str sender: The person sending the message :param str recipient: The recipient of the message :param str message_body: The body of the message :param priority: The priority of the message, can be a number 1-5 :type priority: integer or None :return: the message id :rtype: int :raises ValueError: if the message_body exceeds 160 characters :raises TypeError: if the message_body is not a basestring It is also possible to combine parameter type and description, if the type is a single word, like this:: :param int priority: The priority of the message, can be a number 1-5 Directive Documentation ----------------------- To be determined - likely a variation on the docstring convention reST Documentation ------------------ The majority of libtaskotron's documentation is in the form of reST files which live in the ``docs/source`` directory in the git repository. For more information see: * `reStructuredText Primer `_ * `Sphinx Markup Constructs `_ ReST Headings ^^^^^^^^^^^^^ We use the suggested reST headers as outlined in the `Python documentation style guide on section headers `_ which are: .. in case the text isn't clear, the following excerpt was taken directly from the Python documentation style guide at the link directly above this comment Section headers are created by underlining (and optionally overlining) the section title with a punctuation character, at least as long as the text:: ================= This is a heading ================= Normally, there are no heading levels assigned to certain characters as the structure is determined from the succession of headings. However, for the Python documentation, here is a suggested convention: * ``#`` with overline, for parts * ``*`` with overline, for chapters * ``=``, for sections * ``-``, for subsections * ``^``, for subsubsections * ``"``, for paragraphs