Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Further improves CONTRIBUTING #334

Merged
merged 7 commits into from
Mar 1, 2022
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
221 changes: 203 additions & 18 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,29 @@ fantastic project. There are several ways to contribute:
* write more unittests (we dare you to do that :godmode:)

Before attempting any development, please install HADDOCK3 following the
instructions in the [INSTALL](INSTALL.md) file.
instructions in the [INSTALL](INSTALL.md) file. Afterwards, follow the
instructions in this file.

## Contributing new code
## 1. Contributing new code

HADDOCK3 has two main testing workflows. Here, within the repository, we
test the HADDOCK3's Python shell, code style, and building. Our
test the HADDOCK3's Python shell, code style, and package building. Our
Continuous Integration (CI) pipeline is based on
[tox](https://tox.wiki/en/latest/index.html) and GitHub Actions.
[tox][tox] and GitHub Actions. We will
explain you how to use them.

To contribute to the HADDOCK3's Python shell, follow these steps:

1. [Fork](https://www.earthdatascience.org/workshops/intro-version-control-git/about-forks/) the HADDOCK3 repository
1. [Fork][fork] the HADDOCK3 repository
2. Create a new branch in your fork (`git checkout -b <new_branch_name>`)
3. Develop your code and tests:

1. HADDOCK3 source is in `src/haddock`. Always implement code in
the lowest Python version supported (this case is 3.9)
the lowest Python version supported (this case is 3.9).
2. Tests sit in the `tests/` folder. Use
[pytest](https://docs.pytest.org/en/6.2.x/) for testing.
3. See more details on how to contribute with code and tests in the
subheadings below.

4. While you are developing (or when you think you have finished), you can
(should) use our `tox` environments to test your code. Use the
Expand All @@ -42,17 +46,20 @@ To contribute to the HADDOCK3's Python shell, follow these steps:

5. You can work on these `tox` tests until they all pass green before
submitting your PR.
6. We also have an `examples` folder with `test` cases that you can run
6. We also have an `examples` folder with test cases that you can run
joaomcteixeira marked this conversation as resolved.
Show resolved Hide resolved
(should) to ensure the integrity of the python shell as a whole:
1. Navigate to any of the examples folder and run the `-test.cfg`
file (see [USAGE](USAGE.md)).
2. If you have a powerful computer and want to run all tests in a
row, navigate to the `examples` folder and run `python run_tests.py
-b`. The `-b` flag ensures the run will stop asap an error is found.
3. if your computer is not powerful enough, you can ask us to run
those tests once you submitted the pull request.

7. Add a list of your new additions to the `CHANGELOG.md` file by
adding a new sub-header as described bellow. This is mandatory for `tox
-e build` to pass.
-e build` to pass. Note this applies only after we have released the
stable `3.0.0` version.

```markdown
# Changelog
Expand All @@ -65,17 +72,195 @@ adding a new sub-header as described bellow. This is mandatory for `tox
(... the rest of the file ...)
```

7. If you have difficulties with `tox`, let us know. These `tox` tests
8. If you have difficulties with `tox`, let us know. These `tox` tests
are the same that run on the GitHub Actions once you send the PR. So,
sending the PR is another way to ensure all tests pass.

8. Submit your PR if you haven't done so yet :wink:
9. Submit your PR if you haven't done so yet :wink:

1. Now, GitHub allows submitting "Draft PRs" you can use this
1. GitHub allows submitting "Draft PRs". You can use this
option to let us know you are working on some new good stuff so we
can help you from the beginning.

## Contributing with documentation
### 1.1 Contributing with code (additional details)

**You should also know that...** HADDOCK3 folders, files, and code
follow a well defined structure with very specific patterns. Inside each
source folder you will (likely) find a `README` file describing the
structure of the folder and presenting guidelines on how to better
contribute to that folder and respective files. Summarizing here:

* New command-line clients go in the `clis/` folder. See how the current
clients here created and use that as a template. Remember to update also the
`setup.py` file.
* Add any new functions that you foresee are general and
could serve different places in the code to the `libs/` folder. Find a
`lib*.py` files that would serve your purpuses, otherwise create a new
one.
* Any plug-in like functionality, for example *"check if input is
correct"*, should go into its own python module inside the `gear/`
folder. Any variables, functions, and classes related only to that
implementation should go all inside the same module (Python file).
* Any general hard definitions, or physical constants, should go in the
`core/` folder.
* If you want to implement a new HADDOCK3 module, navigate to the
`modules/` folder and follow the instructions in the `README` file
there. You will see that all folders and files follow a pattern.
* Talk with us before developing any CNS related part.

### 1.2 Contributing with tests (additional details)

Inside the `tests/` folder you will find several `test_*.py` files.
Normally, each file has the tests for each `*.py` file in the source. If
you create new `*.py` files you should create a new test file of the
same name, `test_new_file_name.py`. Aim at 100% test coverage for the
code you have created. Write tests according to [pytest][pytest]. You
can see examples in our `test_*.py` files. You can run the tests using
the `tox -e py39` commands explained above. Or, if you want to run the
tests for a singly file use `tox -e py39 -- tests/test_myfile.py`.

### 1.3 Dependencies

HADDOCK3 is highly interconnected with other projects. Many of them use
HADDOCK3 core functionalities. Therefore, we aim to keep HADDOCK3 with
the lowest dependency footprint possible. Avoid adding dependencies when
developing new functionalities. How?

1. Use the Python standard library as much as possible.
1. Numpy is always allowed.
1. You need a small function from a large library. Try to reimplement it
yourself with the Python standard library.
1. If you can't, talk first with
us by opening an issue.
1. You need a big and complex function or maybe a whole python file from
another project. If licenses are compatible, copy their code to the
HADDOCK3 repository writing all necessary headers to grant authorship
and comply with license requirements.
1. If licenses aren't compatible, talk is us. We may have an
alternative.
1. Your new module largely depends on a library and reimplementing or
copying is not an option. Then, consider if we can use that dependency
as a runtime dependency (like `gdock` or `lightdock`) instead of an
installation dependency.
1. Nothing of the above is possible. You **really** need an install
dependency. Talk with us before.

### 1.4 Code style

HADDOCK3 follows nice code style rules. These are *almost* hard rules,
but there is some room for exceptions - common sense prevails. When
developing code, run `tox -e lint` to inspect if your code follows our
conventions. We use [flake8][flake] with the [following rules][fr] and
docstrings follow [numpydoc][numpydoc] style. You can hold on our code
for style. Nevertheless, here's a dummy code snippet for your reference.
Line have a soft max of 80 chars.

```python
"""Module's docstring."""
# any comments. You can add here licensing stuff
# first import standard library
import os
from path import Pathlib

# import third library
import numpy as np

# import from haddock3
from haddock import log
# multiline import
from haddock.libs.libio import (
lib1,
lib2,
lib3,
lib4,
)


# all this are possible
GLOBAL_VARIBLE = None
_hidden_global_variable = None

avoid_lower_case_globals = None


def my_nice_func(arg1, arg2, arg3):
"""Docstring here."""
# do stuf

# if the function has many arguments, separate them by new lines.
# mind the identations
def my_nice_func_with_big_name(
var1,
var2,
var3,
named_var1="something",
named_var2="else",
**kwargs,
):
"""Docstring here."""
# do stuff
return


multiline_list = [
var1,
var2,
var3,
var4,
]

multiline_dict = {
"key1": 1,
"key2": 2,
"key3": 3,
"key4": 4,
"key5": 5,
}

# separate comprehensions by sections if line don't fit 80 chars
# same for dictionaries
cool_list_comprehension = [
dome_some_long_stuff(i)
for i in some_iterable
if validate(i)
]

double_quotes_allowed = "string"
single_quotes_allowed = 'string'
# don't try to homogenize quotes all around the code, respect the
# original input.

# define first use later
generator_with_a_large_name = zip(
iter1,
iter2,
iter3,
iter4,
iter5,
)

for a, b, c, d, e in generator_with_a_large_name:
# do stuff

# use noqa: E501 for slightly long lines, in case splitting into
# multiple lines reduces readability
this_is_a_long_line = that_makes_no_much_sense(to_separate, in_multiple_lines, abcd) # noqa: E501
```

### 1.5 Code structure

Write code in the form of small functions, because small functions are
easier to test. Combine small functions to compose larger functions. If
you need to use a global variable in a function, pass it as a default
value of a parameter. Avoid using complex classes, or avoid using
classes at all, unless you need to maintain a state or you really know
what you are doing. Flat is better than nested (though it's harder to
write, but it's easier to maintain and read). Use long variable names if
needed. Write comments that explain why you do stuff, and not how you do
stuff. Use the `TODO:` flag in your comments to note something for the
future. If needed, raise an issue.

## 2. Contributing with documentation

HADDOCK3 has (will have) two sources of documentation: 1) the library
documentation itself that is built from code docstrings and `.rst` pages
Expand All @@ -85,10 +270,10 @@ talk with us before start working. On the other hand, if you want to
improve code's documentation, go for it following the same procedure as
described above for *code contributions*.

## You should also know that...

HADDOCK3 folders, files, and code follow a well defined structure with
very specific patterns. Inside each source folder you will (likely) find
a `README` file describing the structure of the folder and presenting
guidelines on how to better contribute to that folder and respective
files.
[tox]: https://tox.wiki/en/latest/index.html "tox"
[fork]: https://docs.github.com/en/get-started/quickstart/fork-a-repo
[pytest]: https://docs.pytest.org/ "pytest"
[flake]: https://flake8.pycqa.org/en/latest/ "flake8"
[fr]: https://github.com/haddocking/haddock3/blob/b44304f0a1509d44d9689d7e2e4124f0ae3af0a1/tox.ini#L116-L130
[numpydoc]: https://numpydoc.readthedocs.io/en/latest/format.html