ProMod3 Setup¶
The following should give an overview of how this project is set up. Anyone planning to develop parts of ProMod3 should read this! Important topics are Git branches, the directory structure and tightly linked with this also CMake.
Git Branches¶
Basically we have two, sometimes three major branches. master
, develop
and in front of a new release a dedicated release branch. For bugs, hotfix
branches of a rather short life are used.
master
is the stable branch, corresponding to a released version. It is
solely fed by a release or hotfix branch.
Release branches, usually labelled release-<VERSION>
, are branched of
develop
to fix features and thoroughly test them before a new major
release. Once everything looks trustworthy, such a branch is merged into
master
and since there should be a few bug fixes in, master
is merged
into develop
. Bugs are fixed in dedicated hotfix branches, which should
only exist for the fix and testing itself. Those are forged from release
branches or master
. If created for master
, they are also merged back
into develop
.
The develop
branch exists to introduce new features up to the level of
whole projects extending ProMod3 and see that they work seamlessly together
with the rest of the system. There do exist a couple of rather strict rules for
what goes into this branch:
Your code must have been (briefly) reviewed by others
There have to be unit tests
It needs to pass
make check
includingdoctest
&linkcheck
Your project needs documentation
It must not break the ability of out-of-source builds
The reason to be a bit restrictive on branches which end up in actual releases, should be mostly obvious: ProMod3 is used by productive services as a third party toolbox. There it is not an item of active development and people probably have no insight in its internals. So messing up a new release creates a lot of extra work for a lot of people. First for the developer of a service to find out that ProMod3 has turned malicious, then for the maintainer of this package to figure out that its your contribution messing things up and in the end for you, fixing the problems.
The place where you may get messy is your own Git branch within the ProMod3
repository. This is basically where you should develop your project. Once you
created something that could go into a release, tidy things up according to the
rules from above and merge it into develop
. From there it will
automatically find its way into the next release.
To set up your own branch, start from a current develop
branch:
$ git checkout develop # switch to branch develop
$ git pull --rebase # update branch develop
$ git checkout -b <BRANCHNAME> # create branch <BRANCHNAME> and switch to it
Over time, develop
may recognise some changes, e.g. new features, which you
want to make use of in your project. Keeping your branch up to date is a three
step process. Git does not allow updates on top of changed code, so either
changes have to be committed, or if in the middle of implementing something,
stored away temporarily. Making commits is straight forward:
$ git commit -m '<DESCRIPTION>' # commit changes including a comment
Hiding your changes away from Git just for updating files is a bit more involved. Everything is easily stored on an internal stack and needs to be fetched from there, once the branch was updated. One major problem in the past was a possible loss of code by those operations. If the update changes a file you have changed, too, and stashed away, this may end up in a non-resolvable merge conflict and your changes are lost. Usually the log tells you, which files were recently modified. Moving all current changes to the stack is achieved by:
$ git stash save
To revive them, use:
$ git stash pop
After cleaning up your branch, switch to develop
, update it and switch back:
$ git checkout develop
$ git pull --rebase
$ git checkout <BRANCHNAME>
Now for actually updating your branch, there are two different ways: merging
and rebasing. A rebase may only be done, if you never pushed your branch to
the origin of the repository (otherwise you will mess up history, in the worst
case develop
may be unusable once you merge):
$ git rebase develop
For branches which are available to others, do a proper merge:
$ git merge develop
This may require some manual conflict solving and will end up in a merge commit.
Git Hooks¶
Git hooks are scripts invoked by Git in connection to certain commands. ProMod3 currently provides one for commit. It is installed by
$ cp extras/pre_commit/pre-commit .git/hooks/
Its task is applying coding standards and doing a bunch of other checks on the
files involved in a commit. Everything around the script is hosted in
extras/pre_commit/
. The checks can be manually executed with
$ python .git/hooks/pre-commit
If you ever have to skip the hook,
$ git commit --no-verify
does the trick. But checks are always run on the complete file containing changes, not only on the lines changed. This means if you opt out of an issue, it will reappear next time that very file changes.
For checking Python code, the pre-commit hook employs Pylint, to make sure
we stay close to PEP 8. If you feel the need to make changes to the Pylint
call, please make sure you fully understand what the complaints are. Sometimes
PEP 8 sounds overly restrictive but it may help with performance and
compatibility with Python 3. For ProMod3 it is also important that the code
looks similar throughout the various modules. So do not disable a check because
it just seems inconvenient or you do not understand why Pylint is croaking at
what looks like ‘working’ code. But then there are also cases where Pylint is
not smart enough to cope with valid PEP 8 code. For changes with valid cause,
the configuration flushed into Pylint may be found at
extras/pre_commit/pm3_csc/filecheck/pylintrc
and
extras/pre_commit/pm3_csc/filecheck/pylint-unittest-rc
. The latter one
is invoked on unit test code, where we may go a little bit less restrictive.
Directory Structure¶
The directory structure of the ProMod3 repository is supposed to ‘keep everything together that belongs together’. That is, code, documentation and extra data should be gathered on a per-module basis immediately in the repository root. The directory structure of your module should look like this:
promod3.git/ Project folder
your_module/ Module directory
CMakeLists.txt CMake configuration
data/ Extra data (if needed)
CMakeLists.txt CMake configuration
...
doc/ Documentation
CMakeLists.txt CMake configuration
your_module.rst Overview/frame of your module
...
pymod/ Python code
CMakeLists.txt CMake configuration
__init__.py Init file needed for import
submodule1.py Code
...
src/ C/ C++ code
CMakeLists.txt CMake configuration
source1.cc C++ code
source2.hh Header
...
tests/ Unit tests
CMakeLists.txt CMake configuration
data/ Test data (if needed)
...
test_your_module.py Unit tests for your_module
test_submodule1.py Unit tests for submodule1
...
Additionally to the module directories there are a few extra folders:
actions
: Scripts callable aspm <ACTION_NAME>
. See here for details.cmake_support
: Helper functions for CMake. See here for details.doc
: High-level documentation, test scripts (doc/tests
) and a copy of the generated html documentation (doc/html
). The latter must be kept up-to-date at least on themaster
branch. See here for details.extras
: Extra data and information that doesn’t fit anywhere else (e.g. Git hooks or scripts to recreate the binary files).scripts
: Input for scripts that end up instage/bin
CMake¶
The attentive reader may have noticed all the CMakeLists.txt
files in
the directory structure. Those are needed to configure the build system, e.g.
tell it which files have to be considered packaging, compiling, etc.. Also
Python modules are declared there as well as which files belong to the
documentation. CMake is a rather complex topic (unfortunately all usable
build systems seem to be) so we skip a detailed view, here, and just advice you
to go by example. There is a tiny bit of documentation on our additions to
CMake here. If you really need to make changes to the
build system, other than adding new files and modules, you have to dive into
CMake documentation all by yourself and on your own responsibility. You have
been warned.
The stage
Directory¶
Once you hit make in your build directory, a directory stage
in this path will be populated. It just resembles a directory structure as of a
usual Unix file system filled with the build products of ProMod3. The
stage
directory tree can already be utilised. You may import Python
modules from there, use the binaries from stage/bin
, etc..