|
| 1 | +.. CONTRIBUTING {{{1 |
| 2 | +.. _contributing: |
| 3 | + |
| 4 | +************* |
| 5 | +Contributing |
| 6 | +************* |
| 7 | + |
| 8 | +This doc provides information about how to contribute to the MiniCPS |
| 9 | +projects. |
| 10 | + |
| 11 | +.. HOW TO START {{{2 |
| 12 | +
|
| 13 | +============= |
| 14 | +How to start |
| 15 | +============= |
| 16 | + |
| 17 | + |
| 18 | +General design principles |
| 19 | +------------------------- |
| 20 | + |
| 21 | +MiniCPS follows an object-oriented design pattern. It is using ``python2.x`` |
| 22 | +for compatibility reasons with ``mininet``. We are trying to lower the number |
| 23 | +of external dependencies, and eventually move to ``python3.x``. |
| 24 | + |
| 25 | +* Design points: |
| 26 | + |
| 27 | + * separation of concerns (eg: public API vs private APi) |
| 28 | + * modularity (eg: different protocols and state backends) |
| 29 | + * testability (eg: unit tests and TDD) |
| 30 | + * performance (eg: real-time simulation) |
| 31 | + |
| 32 | +* Security points: |
| 33 | + |
| 34 | + * avoid unsafe programming languages |
| 35 | + * user input is untrusted and has to be validated (eg: prepared statements) |
| 36 | + * safe vs unsafe code separation |
| 37 | + * automated static analysis |
| 38 | + |
| 39 | +* Core components: |
| 40 | + |
| 41 | + * ``minicps`` module (should be in the ``PYTHONPATH``) |
| 42 | + * ``examples`` use cases (can be anywhere in the filesystem) |
| 43 | + |
| 44 | + |
| 45 | +Development sytle |
| 46 | +----------------- |
| 47 | + |
| 48 | +MiniCPS is hosted on Github and encourages `canonical submission of |
| 49 | +contributions |
| 50 | +<https://opensource.guide/how-to-contribute/#how-to-submit-a-contribution>`_ |
| 51 | +it uses |
| 52 | +`semantic versioning <http://semver.org/>`_, |
| 53 | +``nose`` for `test-driven development |
| 54 | +<https://in.pycon.org/2009/smedia/slides/tdd_with_python.pdf>`_ and |
| 55 | +``make`` as a launcher for various tasks. |
| 56 | + |
| 57 | +Required code |
| 58 | +--------------- |
| 59 | + |
| 60 | +Clone the ``minicps`` repository: |
| 61 | + |
| 62 | +.. code-block:: console |
| 63 | +
|
| 64 | + git clone https://github.com/scy-phy/minicps |
| 65 | +
|
| 66 | +Add ``minicps`` to the python path, for example using a soft link: |
| 67 | + |
| 68 | +.. code-block:: console |
| 69 | +
|
| 70 | + ln -s ~/minicps/minicps /usr/lib/python2.7/minicps |
| 71 | +
|
| 72 | +
|
| 73 | +Install the requirements using: |
| 74 | + |
| 75 | +.. code-block:: console |
| 76 | +
|
| 77 | + pip install -r ~/minicps/requirements-dev.txt |
| 78 | +
|
| 79 | +Run the tests with: |
| 80 | + |
| 81 | +.. code-block:: console |
| 82 | +
|
| 83 | + cd ~/minicps |
| 84 | + make tests |
| 85 | +
|
| 86 | +Code conventions |
| 87 | +---------------- |
| 88 | + |
| 89 | +The project it is based on PEP8 (code) and PEP257 (docstring). |
| 90 | + |
| 91 | +* Naming scheme: |
| 92 | + |
| 93 | + * Private data: prepend ``_`` eg: ``_method_name`` or ``_attribute_name`` |
| 94 | + * Classes: ``ClassName`` or ``CLASSName``, ``method_name`` and ``instance_name`` |
| 95 | + * Others: ``function_name``, ``local_variable_name``, ``GLOBAL_VARIABLE_NAME`` |
| 96 | + * Filenames: ``foldername``, ``module.py``, ``another_module.py`` |
| 97 | + and ``module_tests.py`` |
| 98 | + * Test: ``test_ClassName`` ``test_function_name`` |
| 99 | + * Makefile: ``target-name`` ``VARIABLE_NAME`` |
| 100 | + * Makers: ``TODO``, ``FIXME``, ``XXX``, ``NOTE`` ``VIM MARKER {{{ |
| 101 | + ... }}}`` |
| 102 | + * Docs: ``doc.rst``, ``another-doc.rst`` \and ``SPHINX_DOC_NAME SOMETHING(`` for |
| 103 | + Sphinx's ``literalinclude`` |
| 104 | + |
| 105 | + |
| 106 | +Module docstring: |
| 107 | + |
| 108 | +.. code-block:: python |
| 109 | +
|
| 110 | + """ |
| 111 | + ``modulename`` contains: |
| 112 | +
|
| 113 | + - bla |
| 114 | +
|
| 115 | + First paragraph. |
| 116 | +
|
| 117 | + ... |
| 118 | +
|
| 119 | + Last paragraph. |
| 120 | + """ |
| 121 | +
|
| 122 | +Function docstrings: |
| 123 | + |
| 124 | +.. code-block:: python |
| 125 | +
|
| 126 | + def my_func(): |
| 127 | + """Bla.""" |
| 128 | +
|
| 129 | + pass |
| 130 | +
|
| 131 | + def my_func(): |
| 132 | + """Bla. |
| 133 | +
|
| 134 | + :returns: wow |
| 135 | + """ |
| 136 | +
|
| 137 | + pass |
| 138 | +
|
| 139 | +Class docstring to document (at least) public methods: |
| 140 | + |
| 141 | +.. code-block:: python |
| 142 | +
|
| 143 | + class MyClass(object): |
| 144 | +
|
| 145 | + """Bla.""" |
| 146 | +
|
| 147 | + def __init__(self): |
| 148 | + """Bla.""" |
| 149 | +
|
| 150 | + pass |
| 151 | +
|
| 152 | +.. }}} |
| 153 | +
|
| 154 | +.. PROTOCOLS {{{2 |
| 155 | +
|
| 156 | +========= |
| 157 | +Protocols |
| 158 | +========= |
| 159 | + |
| 160 | +Compatibility with new (industrial) protocols depends on the availability of |
| 161 | +a good open-source library implementing that protocol (eg: ``pymodbus`` for |
| 162 | +Modbus protocols). |
| 163 | + |
| 164 | +If you want to add a new protocol please look at the ``minicps/protocols.py`` |
| 165 | +module. ``Protocol`` is the base class, and the |
| 166 | +``[NewProtocolName]Protocol(Protocol)`` should be your new child class |
| 167 | +(inheriting from the ``Protocol`` class) containing |
| 168 | +the code to manage the new protocol. A good point to start it to take a look |
| 169 | +at ``tests/protocols_tests.py`` to see how other protocols classes |
| 170 | +are unit-tested. |
| 171 | + |
| 172 | +If you want to improve the compatibility of a supported protocol please take |
| 173 | +a look at its implementation and unit-testing classes. For example, look at |
| 174 | +``ModbusProtocol(Protocol)`` and ``TestModbusProtocol()`` if you want to improve |
| 175 | +the Modbus protocol support. |
| 176 | + |
| 177 | +.. }}} |
| 178 | +
|
| 179 | +.. STATES {{{2 |
| 180 | +
|
| 181 | +====== |
| 182 | +States |
| 183 | +====== |
| 184 | + |
| 185 | +The same reasoning presented in the Protocols section applies here. The |
| 186 | +relevant source code is located in ``minicps/states.py`` and |
| 187 | +``tests/states_tests.py``. |
| 188 | + |
| 189 | +.. }}} |
| 190 | +
|
| 191 | +.. TESTING {{{2 |
| 192 | +
|
| 193 | +======== |
| 194 | +Testing |
| 195 | +======== |
| 196 | + |
| 197 | +Unit testing is hard to setup properly! Please if you find any inconsistent unit test or |
| 198 | +decomposable unit test or you want to add a new one then send a PR. |
| 199 | + |
| 200 | +.. }}} |
| 201 | +
|
| 202 | +.. EXAMPLES {{{2 |
| 203 | +
|
| 204 | +======== |
| 205 | +Examples |
| 206 | +======== |
| 207 | + |
| 208 | +Please feel free to send PRs about new use cases that are not already present |
| 209 | +in the ``examples`` directory. |
| 210 | + |
| 211 | +.. }}} |
| 212 | +
|
| 213 | +.. DOCS {{{2 |
| 214 | +
|
| 215 | +======== |
| 216 | +Docs |
| 217 | +======== |
| 218 | + |
| 219 | +All the docs are stored in the ``docs`` folder. We are using ``sphinx`` to |
| 220 | +render the docs and the ``rst`` markup language to write them. Some of the |
| 221 | +docs are automatically generated from the code and others are written by |
| 222 | +hands. |
| 223 | + |
| 224 | +To build you documentation locally use one of the target of the ``Makefile`` |
| 225 | +present in the ``docs`` folder. For example, to build and navigate an html |
| 226 | +version of our docs type: |
| 227 | + |
| 228 | +.. code-block:: console |
| 229 | +
|
| 230 | + cd docs |
| 231 | + make html |
| 232 | + firefox _build/html/index.html |
| 233 | +
|
| 234 | +Please send a PR if you find any typo, incorrect explanation, etc. |
| 235 | + |
| 236 | +.. }}} |
| 237 | +
|
| 238 | +.. }}} |
| 239 | +
|
0 commit comments