Source code for citadel.nodes.branch

#!/usr/bin/env python

import logging
import re

import citadel.nodes.node
import citadel.tools
import citadel.scm


[docs]class Branch(citadel.nodes.node.Base): """:synopsis: Conditional execution based source control's branch name. :requirements: git and/or accurev binary in the path :platform: Any :param name: A regular expression which will test the current branch's name :type name: required **Usage** .. code-block:: yaml :linenos: build: preproduction: name: (master|integration) maven: lifecycle: clean install production: name: prod maven: lifecycle: clean deploy .. note:: This construct is special since any unknown module will be tested to see if it matches the criteriae to become a node of type ``branch``. This test is done by inspecting the children of the node. If any of the children contain a ``name`` key, a ``branch`` is instanced and normal operation will run as documented below. Otherwise, all nodes fraternal to ``name`` will be ignored. The branch module is never used directly by itself. To enable conditional execution depending on environmental factors (in this case the underlying source control management), the branch module was created, enabling the same citadel file to be executed in multiple environments. Since each environment is very particular to every project/organization, the name of the possible environments is left to the user's choice and has no impact on the functionality itself (so long as it doesn't match an already existing module). **Example (good)** .. code-block:: yaml :linenos: :emphasize-lines: 2 deploy: homeinfotainment: name: infotainment ansible: inventory: $ANSIBLE_HOME/home playbook: $ANSIBLE_HOME/playbooks/deploy_infotainment.yml **Example (bad)** .. code-block:: yaml :linenos: :emphasize-lines: 2 deploy: maven: name: infotainment ansible: inventory: $ANSIBLE_HOME/home playbook: $ANSIBLE_HOME/playbooks/deploy_infotainment.yml As mentioned, the string which names the environment is completely arbitrary and does affect the logic underneath. Which means that: .. code-block:: yaml :linenos: :emphasize-lines: 2 deploy: hello: name: somebranch script: - echo "hello world" Is functionally equivalent to: .. code-block:: yaml :linenos: :emphasize-lines: 2 deploy: world: name: somebranch script: - echo "hello world" The ``name`` is a regular expression (as handled by python's ``re`` module) and can be used liberally: .. code-block:: yaml :linenos: deploy: some_environment: name: (!prod) This would match any branch which isn't named **prod**. The heuristic for matching branches depends on the driver being used. Currently both **git** and **AccuRev** are supported, and they are tested in that order. All the SCMs are testing and the last one succeeding takes precendence. In this case, if a directory is both an AccuRev workspace and a git repo, the AccuRev workspace would take precendence and be used for the actual evaluation of the branch's name. Git's branch name is detected by running: .. code-block:: bash git rev-parse --abbrev-ref HEAD AccuRev's branch name is detected by running: .. code-block:: bash accurev info """ def __init__(self, yml, path): branch_name = citadel.scm.get_client().get_active_branch() if re.search(yml, branch_name): logging.debug('Matched branch name for %s: %s', '/'.join(path), branch_name) super(Branch, self).__init__(yml, path) else: logging.debug('Branch name mismatch for %s. Expected [%s] instead got [%s])', '/'.join(path), yml, branch_name) self.skip = True