Skip to content
Snippets Groups Projects
CONTRIBUTING.md 6.27 KiB
Newer Older
Hinkle, Jacob D.'s avatar
Hinkle, Jacob D. committed
# Table of Contents
<!-- toc -->

- [Contributing to Ptychopath](#contributing-to-ptychopath)
- [Development workflow](#development-workflow)
- [Codebase structure](#codebase-structure)
- [Coding style](#coding-style)
Hinkle, Jacob D.'s avatar
Hinkle, Jacob D. committed
- [Unit testing](#unit-testing)
- [Benchmarking](#benchmarking)
Hinkle, Jacob D.'s avatar
Hinkle, Jacob D. committed
- [Writing documentation](#writing-documentation)

<!-- tocstop -->
Hinkle, Jacob D.'s avatar
Hinkle, Jacob D. committed

## Contributing to Ptychopath

We welcome contributions from anyone using this code. The best way to start contributing is to search the issue tracker in this repository and either comment on existing issues or file new ones if there are topics not yet covered. We can advise how to contribute after that but please do read the [Development workflow](#development-workflow) section below for a short description of our workflow before doing so.

## Development workflow
Hinkle, Jacob D.'s avatar
Hinkle, Jacob D. committed

We use a very basic [Gitlab flow](https://docs.gitlab.com/ee/topics/gitlab_flow.html). The following are the main points:

- We have a single main branch called `main` which is meant to be kept in a working state. New users can clone our repository and expect the tests to pass and for its documentation to be complete and match the implementation.
- We have no long-lived branches. Do not create a branch without a plan or conditions under which it will be merged back to `main`.
- Development of new features begins by filing a new issue in the gitlab issue tracker. The issue description should be as concise as possible and ideally state a course of action. Commentary may take place on the issue but if any developer wishes to attempt to address the issue, they will use the gitlab web interface to "Create merge request" on that issue.
- Merge requests are used to create git branches in which commits can be pushed addressing a particular issue or set of issues.
- Please take care to write good commits. This means adding files manually using `git add`, followed by `git commit`. I often write multiple commits in order to break my recent changes into logical groups. This can be done very easily using `git add -p` to only commit parts of files. I typically then use `git commit -v` which opens an editor and lets me write a good commit message, and also shows a patch with all the changes to be committed.
Hinkle, Jacob D.'s avatar
Hinkle, Jacob D. committed
- We use descriptive commit messages to aid in collaboration over gitlab. See [How to Write a Git Commit Message](https://chris.beams.io/posts/git-commit/) for best practices that we strive to follow with each commit.
- When a merge request is deemed to have sufficiently addressed the issue it was created from, it is merged to main. This assumes the tests pass CI. If not, we require further commits to fix any broken tests before merging.

## Codebase structure

The top level of this repository contains accessory files like this `CONTRIBUTING.md` file, as well as a number of directories:

- `ptychopath/`: the source directory for our python module. Submodules are implemented as `.py` files and directories within this directory.
- `docs/`: the Sphinx source for our documentation. See [Writing documentation](#writing-documentation) below.
- `tests/`: unit tests written using PyTest. See [Unit testing](#unit-testing) below.
- `notebooks/`: Jupyter notebooks exploring new concepts. This is where experimental code is shared before it is engineered to become part of the main library in `ptychopath/`.

## Coding style

We use the [black](https://black.readthedocs.io/en/stable/) formatter to automatically format source code in this repository. This can be used painlessly by simply installing `pre-commit` with pip (this happens automatically if you run `pip install -r requirements.txt`), then running the following command from the top level directory of this repository once:
```
```
After that, whenever `git commit` is run, the code formatter will run on the staged files, and if any changes are made due to formatting, the commit will be cancelled. You will then need to `git add` the formatting changes to stage them before running `git commit` again. You can always run `pre-commit run --all-files` in order to ensure all the code in the repository is formatted properly.

Note that after writing your commit message, its format will also be checked. If this fails you will need to run `git commit` again and address formatting errors.

Hinkle, Jacob D.'s avatar
Hinkle, Jacob D. committed
## Unit testing

We mostly follow test-driven development, in which we write tests as we are developing new functionality. The tests are meant to specify invariants and assumptions about how the new functionality must behave.

- Run tests using `py.test` or `pytest`
- In order prevent a backlog of broken tests, all tests must pass CI before merge requests will be merged to `main`.

## Benchmarking

We use [pytest-benchmark](https://pytest-benchmark.readthedocs.io) to do simple
performance benchmarking. The simplest way to add a benchmark is to simply add a test that takes an argument named `benchmark`. That argument is callable. For example to benchmark an existing function called `foo` with arguments `x, y, z`, you can write the following in `tests/test_foo.py`:
```python
def test_foo(benchmark):
    benchmark(foo, x, y, z)
```
This is particularly powerful when used in conjunction with [pytest parametrized tests](https://docs.pytest.org/en/6.2.x/parametrize.html).

More detailed profiling can be done using NVIDIA tools like `nsys` and `dlprof`, or with python profiling tools like the built-in `cProfile` module.

Hinkle, Jacob D.'s avatar
Hinkle, Jacob D. committed
## Writing documentation

We use [Sphinx](https://www.sphinx-doc.org/) for documenting our code. Please follow these guidelines:

- When introducing a new module, ensure that it has a corresponding topic file under `docs/source/modules/`.
- When creating new modules, functions, classes, or methods, please include a docstring.
- Global variables can be referenced by adding a multiline string after the definition. See the source for [iexp](http://lucky:5050/modules/fourier.html#ptychopath.fourier.iexp) for an example.
- If there are relevant references, please use the syntax `` :cite:t:`foo` `` and `` :cite:p:`bar` `` within your docstrings and add the reference to `docs/source/refs.bib`.
- Domain-specific terminology can be introduced by adding an entry to `docs/source/glossary.rst` and referencing terms by the `` :term:`baz` `` syntax.
Hinkle, Jacob D.'s avatar
Hinkle, Jacob D. committed
- New topics can be introduced and linked from `docs/source/index.rst` as well.
- Please try to follow the Google docstring format.