Contributing Guide
Where to start?
All contributions, bug reports, bug fixes, documentation improvements, enhancements, and ideas are welcome.
Get started by looking through the list of open issues to explore bugs or improvments suggested by others. If an open issue resonates, comment on it and ask how you might help.
If you have a new suggestion open a new issue to share your ideas and begin a discussion about potential solutions. If you are reporting a bug, provide enough detail so others can reproduce the bug.
Contributing Code or Documentation
Once you have identified or created an issue that you would like to address, use Git to create a feature branch to start modifying any file in the repository, whether it is source code, test code, examples, or documenation.
Git Best Practices
Thie project follows GitFlow workflow conventions, in which branches serve these specific purposes:
main
branch reflects the latest releasedevelop
branch is a functioning candidate for the next releaseshort-lived feature branches are created from
develop
to actively work on an issue.
To contribute, create a feature branch from develop
, work on your updates, commiting often (at least every couple of hours of work), once your update is working issue a merge request back to the develop
branch, and ask someone to review your merge request.
Tools vs Utilities
The main functions of FCPGtools exist in two module files, tools.py
and utilities.py
. It is important to understand the different purpose of these modules before contributing.
tools.py
contains functions for the main workflow used by end-users, including all that read/write files.
Use from
fcpgtools
namespaceFuture edits should always be backward compatible for all v2.x releases, to accept the same inputs and provide the same outputs.
utilties.py
contains functions used by tools.py, most often repeatedly, and also accessible to the user.
Use from
fcpgtools.utilities
namespaceFuture edits could be allowed to break backward compatibility within v2.x releases, as these are primarily intended to be used internally by functions in tools.py.
Terrain Engines
Adding a new terrain_engine
or expanding a terrain_engine
’s functionality requires an understanding of a specific object oriented structural subtyping capability introduced with Python 3.8.
The TerrainEngine geospatial methods are specified as Python Protocols in the terrain_engine/protocols.py
. These Protocols define the abstract signature of the various geospatial methods to be implemented in separate classes using python geospatial libraries to perform the necessary geospatial operations.
To add additional TerrainEngines the developer should define a new class and implement the protocols (or a subset) defined in terrain_engine/protocols.py.
To add additional geospatial functions the developer should first define a new protocol in the terrain_engine/protocols.py file. That protocol will define the abstract signature of the new geospatial method (including function name, arguments, and return type). Once a protocol is defined, a concrete implementation of the protocol can be developed in any of the various TerrainEngines.
Note a future refactoring should consider leverage a plugin architecture for easier integration of third party TerrainEngines.
Custom Types and Formats
FCPGtools leverages numerous custom types and formats that are specified in the custom_types.py
module.
Input file types
To support a new input file type, update either the custom_types.RasterSuffixes
or custom_types.ShapefileSuffixes
tuple with the relevant file suffix (i.e., .nc
). Then add an elif
statement under tools.load_raster()
or tools.load_shapefile()
to handle the new extension type. Similarly, to support saving to new file type, add an elif
statement to tools.save_raster()
or tools.save_shapefile()
.
Adding a new D8 Flow Direction Raster (FDR) format
To support a new D8 Flow Direction Raster (FDR) format, simply add a key-value mapping in custom_types.D8ConversionDicts
where the key is the new formats name in lower case, and the value is a dictionary mapping each cardinal direction + nodata to an integer value.
Issuing a release (PyPi maintainers only)
Start with a fresh
fcgptools_base
environment by cloning ourenvironment.yml
file.Search the entire directory to find references to the version number, and increment appropriately.
Make a merge-request on GitLab to merge your feature or develop branch into the master branch. Once successful, switch to the master branch.
Using the
conda
terminal, navigate to/FCPGtools
containing thepyproject.toml
andpoetry.lock
files.Run the following commands in sequence to resolve the environment dependencies, install the updated copy of
fcpgtools
into your environment, then build a local wheel file for distribution:poetry lock poetry install poetry build
NOTE: The reason we use
poetry install
last is to make sure there are no issues installing the packaged wheel into our recommended virtual environment.
Use
poetry publish -u {YOUR-PyPI-USERNAME} -p {YOUR-PyPI-PASSWORD}
to publish the package to ourPyPI
distribution.Issue a new release on the GitLab repository “releases” page. Inform the users of all relevant updates, change to dependencies, and motivation behind the latest release.