.. _development: .. _contributing: *********** Development *********** Welcome to the Eelbrain Contributor's Guide! This page is a gentle introduction to contributing: it explains how to get involved, report issues, and propose changes, and how we handle testing, style, and documentation. This guide is meant to be useful for all contributors—if you spot gaps or have suggestions, please let us know through the issue tracker. .. contents:: Table of Contents :depth: 2 :local: The Development Version ----------------------- Eelbrain is hosted on `GitHub `_. Development takes place on the ``main`` branch, while release versions are maintained on branches called ``r/0.40`` etc. For further information on working with GitHub see `GitHub's instructions `_. The repository contains mamba environments that include everything needed to use Eelbrain except Eelbrain itself. To install the development version: First, clone the repository (or your `fork `_), and change into the repository directory: .. code-block:: console $ git clone https://github.com/Eelbrain/Eelbrain.git $ cd Eelbrain Two environment files are available: - ``env-dev.yml``: the full development environment (``eeldev``), including tools for building documentation, optional neuroimaging packages, and GUI support. - ``env-test.yml``: a leaner environment (``eeltest``) used for CI, suitable when you only need to run tests and don't require the full documentation or dev tooling. Generate the ``eeldev`` environment (or substitute ``env-test.yml`` / ``eeltest`` for the lighter alternative): .. code-block:: console $ mamba env create --file=env-dev.yml The development version of Eelbrain can then be installed with ``pip``: .. code-block:: console $ mamba activate eeldev $ pip install -e . On macOS, the ``$ eelbrain`` shell script to run ``iPython`` with the framework build is not installed properly by ``pip``; in order to fix this, run: .. code-block:: console $ ./fix-bin In Python, you can make sure that you are working with the development version: $ python >>> import eelbrain >>> eelbrain Opening Issues -------------- Bug reports and feature requests are welcome on the GitHub `Issue Tracker `_. If you're unsure whether something is a bug or an enhancement, feel free to ask in an issue. For other questions, consider using GitHub `Discussions `_. **Reporting Bugs** Please open a bug-report `Issue `_ and include as much information as possible. Effective bug reports help us fix issues faster. **Bug fixes** If you notice a bug and are able to fix it, we welcome a pull request. Ideally, include a test to preempt future regressions (see :ref:`dev-testing`). **Feature Requests** If you are thinking about implementing a new feature, please open an issue first to discuss the design. This keeps efforts aligned with the roadmap and reduces the chance of duplicate work. Pull Request Workflow --------------------- We follow a standard GitHub `workflow for Pull Requests `_ (PRs). .. IMPORTANT:: **Keep PRs small and focused**: Each PR should address a single issue or feature. This allows for faster turnaround, which makes reviewing easier and minimizes the chance for code drift between your PR and the ``main`` branch. The steps below outline the recommended workflow. 1. **Create a Fork** of `Eelbrain `_. 2. **Create a Branch**: Create a new branch from ``main`` for each feature or fix. 3. **Commit Changes**: Make your changes and commit them. Individual commit messages are squashed together during merge, therefore it is useful to have good descriptions in the commit messages that apply to the PR as a whole. Less useful commit messages (eg. "fix CI" when CI is not broken before PR) will be removed during merge. 4. **Dependency changes**: Any changes to the dependencies should be updated in ``pyproject.toml``, ``env-dev.yml``, ``env-test.yml``, and ``env-readthedocs.yml`` as appropriate. 5. **Test Locally**: Add tests for new features and bug fixes to ensure code quality and prevent regressions. Run existing tests to make sure nothing breaks (see :ref:`dev-testing`). Run the ``pre-commit`` tools to ensure compliance with our coding standards (see :ref:`code-style` below). 6. **Push to Your Fork**: Push your branch to your fork on GitHub. 7. **Open a Pull Request (PR)**: - **Use Draft Mode**: `Draft mode `_ allows you to make sure all checks pass before inviting feedback. - Give the PR a descriptive title and describe the intended change. `Link to relevant issues `_ and discussions in the PR description. - Monitor the checks, including: - Tests: in case of failures, you can inspect the errors that occurred. - Codecov: tells you whether tests cover your changes sufficiently. - Docs: if you modified the documentation, ensure it builds as intended. - **Ready for Review**: Switch the PR status to "Ready for Review" when the implementation is complete and all checks pass. Invite reviews from specific contributors (only if they are specifically relevant or have previously agreed to review this PR). 8. **Code Review**: The code review process is a collaborative effort to improve code quality. - Apply feedback globally; if a reviewer notes an issue in one file, check if it exists elsewhere in your changes. - When you have addressed all reviewer comments and checks are passing, signal that the PR is ready for another review by leaving a comment (e.g., "All comments addressed, ready for re-review") or re-requesting a review from the contributors whose comments you addressed, via the GitHub UI. This explicitly notifies the maintainers that the code is ready for the next round. - Try to address reviews promptly. Re-review is easier when changes are fresh in mind. in addition, the longer you wait, the more likely your changes will drift from the current codebase. .. _dev-testing: Testing and Validation ---------------------- Tests are embedded throughout the codebase in ``test`` folders. Tests for individual modules are included in folders called ``tests``, usually on the same level as the module. Some tests make use of MNE-Python datasets, which you can download using: >>> mne.datasets.sample.data_path(verbose=True) >>> mne.datasets.testing.data_path(verbose=True) >>> mne.datasets.fetch_fsaverage(verbose=True) Running tests locally (from the project root): .. code-block:: console $ make test # runs all tests $ make test-no-gui # runs tests that do not invoke GUIs $ make test-only-gui # runs only the tests that invoke GUIs $ pytest path/to/test_file.py # runs all tests in a specific file $ pytest path/to/test_file.py::test_func # runs test_func() in path/to/test_file.py For more options, see the `pytest docs `_. An additional test for the :class:`Pipeline` takes longer to run and can be run separately as needed: .. code-block:: console $ pytest --runslow eelbrain/_experiment/tests/test_sample_experiment.py::test_sample_source All pull requests trigger a Continuous Integration (CI) workflow that automatically runs the full test suite. On macOS, tests involving GUIs need to run with the framework build of Python; if you get a corresponding error, run ``$ ./fix-bin pytest`` from the ``Eelbrain`` repository root. .. _code-style: Coding Style and Documentation ------------------------------ **PEP 8 Style and Formatting** To facilitate maintenance and consistent reviews, we follow the `PEP 8 style guide `_. We recommend using tools to ensure compliance: - IDEs like PyCharm and VSCode can fix and alert you to style issues as you code. - `pre-commit `_ can run tools that automatically detect, and often fix, common code style issues. Use ``$ pre-commit run --all-files`` from the project root to run these tools locally. The tools can also be run automatically upon committing changes (see `pre-commit instructions `_). For the specific tools, see ``.pre-commit-config.yaml`` in the project root. **Consistent Naming and API Consistency** To make the library intuitive, we strive for consistency across the API: - **Naming**: Parameter names should be consistent with existing functions (e.g., use ``cmap`` for colormaps, not ``colorscale``). - **Avoid abbreviations**: For new parameters, we generally prefer avoiding abbreviations, as they can be harder to remember. **Type Hints** We use type hints in all function signatures (see :mod:`typing`; e.g., ``def my_function(y: NDVar) -> Figure:``). **Docstrings** - We follow the `numpydoc style `_ for docstrings. - There's no need to duplicate type information in docstrings if it is already present in the signature; the signature is the source of truth. **Documentation Format** - The documentation is written with :mod:`sphinx` in `ReStructured Text `_. Recommended Tools ----------------- For more on Git we recommend the free `Pro Git book `_. The following tools are used by the maintainers and can streamline development: - **SourceTree**: A graphical frontend for git (`link `__). - **PyCharm**: A powerful Python IDE that can handle formatting and testing (`link `__). - **VS Code**: A lightweight, extensible editor with rich Python tooling support (`link `__).