Skip to content

Add instructions for wrapping new module #1687

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

Draft
wants to merge 12 commits into
base: main
Choose a base branch
from
11 changes: 4 additions & 7 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,10 @@ Fixes #

**Reminders**

- [ ] Run `make format` and `make check` to make sure the code follows the style guide.
- [ ] Add tests for new features or tests that would have caught the bug that you're fixing.
- [ ] Add new public functions/methods/classes to `doc/api/index.rst`.
- [ ] Write detailed docstrings for all functions/methods.
- [ ] If wrapping a new module, open a 'Wrap new GMT module' issue and submit reasonably-sized PRs.
- [ ] If adding new functionality, add an example to docstrings or tutorials.
- [ ] Use underscores (not hyphens) in names of Python files and directories.
- [ ] Try to get all checks passing, including style checks and test coverage.
- [ ] Follow the general [pull request guidelines](https://www.pygmt.org/dev/contributing.html#general-guidelines-for-making-a-pull-request-pr).
- [ ] If contributing documentation, follow the guidelines in [contributing documentation](https://www.pygmt.org/dev/contributing.html#contributing-documentation).
- [ ] If contributing code, follow the guidelines in [contributing code](https://www.pygmt.org/dev/contributing.html#contributing-code).

**Slash Commands**

Expand Down
75 changes: 73 additions & 2 deletions doc/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,6 +166,8 @@ To increase the chances of getting your pull request accepted quickly, try to:
- Include an example of new features in the gallery or tutorials.
Please refer to [Gallery plots](contributing.md#contributing-gallery-plots)
or [Tutorials](contributing.md#contributing-tutorials).
If adding a new method/function/class, the gallery example or tutorial should
be submitted in a separate pull request.
* Have a good coding style
- Use readable code, as it is better than clever code (even with comments).
- Follow the [PEP8](https://pep8.org) style guide for code and the
Expand Down Expand Up @@ -467,8 +469,9 @@ function/class/module/method.
### PyGMT Code Overview

The source code for PyGMT is located in the `pygmt/` directory. When contributing
code, be sure to follow the general guidelines in the
[pull request workflow](contributing.md#pull-request-workflow) section.
code, please open an issue first to discuss the feature and its implementation
and be sure to follow the general guidelines in the
[pull request workflow](#pull-request-workflow) section.

### Code Style

Expand Down Expand Up @@ -511,6 +514,74 @@ contains rules for running the linter checks:
make check # Runs ruff in check mode
```

### Wrapping a new GMT module

Wrapping a new GMT module in PyGMT is usually a big task, which will progress
quicker and smoother if done in **small, manageable chunks**. This section
gives an overview of the specific tasks involved in wrapping a new module.

1. Create a ['Wrapper for `<module-name>`' feature request issue](#request-wrapper-for-gmt-module).
2. Open a ['Wrap `<module-name>`' initial feature implementation PR](#initial-feature-implementation).
3. Open an ['Add missing aliases to `<module-name>`' documentation PR](#add-missing-aliases).
4. Open a 'support additional functionality in module' PR (optional).
5. Add ['Gallery example for module' documentation PR](#contributing-gallery-plots).
6. Add ['Tutorial for module' documentation PR](#contributing-tutorials) (optional).

These steps will be tracked in the 'Wrapper for `<module-name>`' issue and the
['wrapping GMT modules'](https://github.com/GenericMappingTools/pygmt/projects/9)
project board. The pull requests can be split between multiple contributors and
Comment on lines +530 to +532
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should either track the module updates in a project board (my preference) or an issue, but not both.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think we should abandon the 'Wrapper for <module-name>' issues entirely or keep the issues/issue-template and just move the checklist to the project board? I think the main benefit of the issues is that from my understanding any GitHub user can open/comment on an issue whereas writing on the project board requires special permissions.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the project board works better for tracking the progress of wrapping a module, and that having a separate issue for wrapping the function is a bit redundant. I see what you mean about the benefits of issues being open to everyone, but my thought is that wrapping modules is a pretty routine process and doesn't need to first be raised as an issue (unlike a bug or a feature request). We can add some/all of the GMT modules to the project board to track their process. Users who don't have write permission are still free to open up an issue requesting a module/feature (or a pull request! 🤞) as a way to let us know that a certain feature would be useful to them.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the benefits of issues being open to everyone

IMHO, issues are also more visible than project boards, so that we may have more potential contributors helping wrap new modules and add more aliases.

there is no obligation for a single contributor to complete all steps. Please
comment on the initial 'Wrapper for `<module-name>`' if you would like to open
a pull request for any of these tasks to avoid redundant efforts.

#### Request wrapper for GMT module

* Find the [*Issues*](https://github.com/GenericMappingTools/pygmt/issues) tab on the
top of the GitHub repository and click *New Issue*.
* Click on *Get started* next to *Feature request - Wrap new GMT module*.
* Follow the prompts for filling out the issue template.

#### Initial feature implementation

First, comment on the 'Wrapper for `<module-name>`' issue that you will be
working on the initial feature implementation. This first pull request should
be as minimal as possible - only adding the required functionality (i.e.,
wrapping the required GMT arguments and supporting the primary input/output
types).

The following steps are common to all initial implementation pull requests that
wrap a new GMT module (e.g., [initial grdfill implementation](https://github.com/GenericMappingTools/pygmt/pull/1276/files)):

* Create a new module `<module-name>.py` in `pygmt/src`. The module docstring
should include the module name and a short description of the functionality
(e.g., `grdfill - Fill blank areas from a grid.`).
* Add a function `<module-name>` to the module. When writing the new function,
it is generally easiest to reference the source code for other functions that
input/output similar object types.
* Add a detailed docstring following the [numpy style guide](https://numpydoc.readthedocs.io/en/latest/format.html).
* Add the function to the import statements in `pygmt/src/__init__.py`.
* Add the function to the import statements in `pygmt/__init__.py`.
* Add the function to appropriate section of the API documentation in `doc/api/index.rst`.
* Add a testing module `test_<module-name>.py` in `pygmt/tests`, following
the guidelines in the [testing your code](#testing-your-code) section.

#### Add missing aliases

After the initial implementation, the missing aliases can be added in a
separate PR (e.g., [add missing aliases to grd2xyz](https://github.com/GenericMappingTools/pygmt/pull/1537/files)).
Comment on lines +568 to +571
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might need to get a newer example once we go with the long option standard in #1932.


* Select a suitable alias for each GMT option, following the guidelines in the
[code style](#code-style) section. Before creating a new alias, check if the
parameter is listed in the `COMMON_DOCSTRINGS` dictionary in
`pygmt/helpers/decorators.py`, if other wrapped GMT modules have a similar
parameter, and if [GMT.jl](https://www.generic-mapping-tools.org/GMT.jl/dev/)
has defined an alias.
* Update the `use_alias` decorator for the `<module-name>` function using the
GMT option as the parameter and the alias as the argument.
* Add the alias and description to the parameters section of the docstring,
using the `fmt_docstring` decorator to add descriptions for parameters
included in the `COMMON_DOCSTRINGS` dictionary.

### Testing your Code

Automated testing helps ensure that our code is as free of bugs as it can be.
Expand Down
Loading