|
| 1 | +# NTIA/ITS Propagation Library Contribution Guide - Python |
| 2 | + |
| 3 | +Thank you for your interest in contributing to this open source software. On this |
| 4 | +page you will get an overview of the contribution workflow from opening an issue, |
| 5 | +creating a PR, reviewing, |
| 6 | +and merging the PR. This page also includes some information about the project |
| 7 | +structures, development workflows, and code styles which are used throughout the |
| 8 | +ITS Propagation Library. |
| 9 | + |
| 10 | +If you are instead interested in usage documentation, please refer to the |
| 11 | +[Propagation Library Wiki](https://ntia.github.io/propagation-library-wiki). |
| 12 | + |
| 13 | +## Contents |
| 14 | + |
| 15 | +- [Found a Bug?](#found-a-bug) |
| 16 | +- [Background for New Contributors](#background-for-new-contributors) |
| 17 | +- [Notes on Code Style](#notes-on-code-style) |
| 18 | +- [Project Structure and CMake](#project-structure-and-cmake) |
| 19 | +- [Documenting Code](#documenting-code) |
| 20 | + |
| 21 | +## Found a Bug? |
| 22 | + |
| 23 | +If you spot a problem with this software, |
| 24 | +[search if an issue already exists](https://docs.github.com/en/github/searching-for-information-on-github/searching-on-github/searching-issues-and-pull-requests#search-by-the-title-body-or-comments). |
| 25 | +If a related issue doesn't exist, we encourage you to open one (even if you |
| 26 | +don't plan to contribute a resolution yourself). Issues may be opened for bugs, |
| 27 | +documentation errors, or feature requests. |
| 28 | + |
| 29 | +## Background for new contributors |
| 30 | + |
| 31 | +The workflow we recommend and describe here follows from best and common |
| 32 | +practices in the Git and GitHub ecosystems. We aim to leverage this workflow, |
| 33 | +especially the elements of code review and approval, to enable open source |
| 34 | +development of robust, trustworthy radio propagation software. Here are some |
| 35 | +resources to help you get started with open source contributions: |
| 36 | + |
| 37 | +- [Set up Git](https://docs.github.com/en/get-started/getting-started-with-git/set-up-git) |
| 38 | +- [GitHub flow](https://docs.github.com/en/get-started/using-github/github-flow) |
| 39 | +- [Collaborating with pull requests](https://docs.github.com/en/github/collaborating-with-pull-requests) |
| 40 | +- [Basic explanation of Git submodules](https://gist.github.com/gitaarik/8735255) |
| 41 | +by [**@gitaarik**](https://github.com/gitaarik) |
| 42 | + |
| 43 | +### Git Submodules |
| 44 | + |
| 45 | +Software in the ITS Propagation Library is implemented primarily in C++. Each |
| 46 | +piece of software has a primary repository which contains the base C++ implementation, |
| 47 | +test data and resources, and common files used by the multi-language wrappers. |
| 48 | +Interfaces for additional programming languages are provided in separate repositories, |
| 49 | +which are linked to the primary repository as [Git submodules](https://gist.github.com/gitaarik/8735255). |
| 50 | +When cloning the primary repository, the submodules are not additionally cloned |
| 51 | +by default. This can be done with the `git submodule init` command. Initializing |
| 52 | +the submodule as part of the parent repository will let you use the build |
| 53 | +configuration from the primary repository to compile the C++ source and place it |
| 54 | +appropriately for use by the wrapper code. If you choose to independently clone |
| 55 | +the wrapper repository, you will likely need to separately download the compiled |
| 56 | +library (for example, a DLL from a GitHub release). |
| 57 | + |
| 58 | +### Contributing on GitHub |
| 59 | + |
| 60 | +If you'd like to solve an existing issue, add a new feature, or modify this software, |
| 61 | +follow these steps when making your changes. |
| 62 | + |
| 63 | +1. Fork the repository. This allows you to make your changes without affecting the |
| 64 | +original project until you're ready to merge them. You can create a fork |
| 65 | +[with GitHub Desktop](https://docs.github.com/en/desktop/contributing-and-collaborating-using-github-desktop/cloning-and-forking-repositories-from-github-desktop) |
| 66 | +or [using the command line](https://docs.github.com/en/github/getting-started-with-github/fork-a-repo#fork-an-example-repository) |
| 67 | + |
| 68 | +1. Create a working branch and start with your changes! Commit changes |
| 69 | +incrementally to your fork. See the sections below for details about unit tests, |
| 70 | +code style, and documentation. |
| 71 | + |
| 72 | +1. When you're done making changes, create a pull request, also known as a PR. |
| 73 | +In your PR, please include a meaningful description of the changes you've made. |
| 74 | +If your PR solves an issue, |
| 75 | +[link to it](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue)! |
| 76 | +Once you submit your PR, a maintainer will review your changes. We may ask questions |
| 77 | +or request additional changes which must be addressed before the PR can be merged. |
| 78 | + |
| 79 | +When your PR is approved and merged, your changes will be a part of the main |
| 80 | +branch of the repository. A new release may or may not be immediately created, |
| 81 | +depending on the changes made. If a new release is not immediately made, your |
| 82 | +changes will be packaged into the next release. |
| 83 | + |
| 84 | +## Notes on Code Style |
| 85 | + |
| 86 | +- In general, variables follow the naming convention in which a single underscore |
| 87 | +denotes a subscript (pseudo-LaTeX format), where a double underscore is followed |
| 88 | +by the units, i.e. `h_1__meter`. |
| 89 | +- Variables are named to match their corresponding mathematical variables in the |
| 90 | +underlying text, when applicable. |
| 91 | +- Wherever possible, equation numbers are provided. It is assumed that a user |
| 92 | +reviewing this source code would have a copy of the relevant text available |
| 93 | +as a primary reference. |
| 94 | +- _For base/C++ repositories_, a `.clang-format` file is included in the root directory. |
| 95 | +Most IDEs support this type of file, which can and should be used to apply uniform |
| 96 | +code styling to C++ source and header files. |
| 97 | +- _For Python wrapper repositories_, a `.pre-commit-config.yaml` file is included |
| 98 | +in the root directory. This file implements multiple hooks for the [pre-commit](https://pre-commit.com/) |
| 99 | +tool, which apply automated formatting to files when they are commited to Git. |
| 100 | +It is recommended to use this tool to autoformat Python code when checked in. |
| 101 | + |
| 102 | +## Project Structure and CMake |
| 103 | + |
| 104 | +Software in the ITS Propagation Library is primarily implemented in C++, then |
| 105 | +wrapped with interfaces exposing the C++ library to users of other languages. The |
| 106 | +primary repository for each software package uses [CMake](https://cmake.org/) to |
| 107 | +handle cross-platform C++ build configuration, C++ unit tests, and generation of |
| 108 | +API documentation (with [Doxygen](https://www.doxygen.nl/)). Many IDEs support CMake |
| 109 | +integration in some form or fashion, and it is recommended that you familiarize yourself |
| 110 | +with any such functionality of your chosen IDE. |
| 111 | + |
| 112 | +This section shows a typical project structure for a primary (i.e., non-wrapper) |
| 113 | +repository. For details about wrapper repositories, refer to their own README files. |
| 114 | + |
| 115 | +```bash |
| 116 | +docs/ |
| 117 | + CMakeLists.txt # Doxygen configuration |
| 118 | +extern/ |
| 119 | + ... # External Git submodules/dependencies |
| 120 | +include/ |
| 121 | + <PackageNamespace>/ # Include namespace folder, e.g. "ITS.Propagation.ITM" |
| 122 | + <HeaderFiles>.h # Library header files go here, e.g. "ITM.h" and "ErrorCodes.h" |
| 123 | +src/ |
| 124 | + <SourceFiles>.cpp # Source files go here, e.g. "LongleyRice.cpp" and "FreeSpaceLoss.cpp" |
| 125 | + CMakeLists.txt # Configures cross-platform build |
| 126 | +tests/ |
| 127 | + data/ |
| 128 | + <TestDataFiles>.csv # Testing data goes here. Does not have to be CSV. |
| 129 | + <TestFiles>.cpp # Unit tests, usually one test file per source file. |
| 130 | + <TestFiles>.h # Any headers used by tests go here as well. |
| 131 | + CMakeLists.txt # CTest+GTest config. Must add names of test files here. |
| 132 | +wrap/ |
| 133 | + dotnet/ # C#/.NET wrapper submodule. Should contain CMakeLists.txt |
| 134 | + matlab/ # MATLAB wrapper submodule. Should contain CMakeLists.txt |
| 135 | + python/ # Python wrapper submodule. Should contain CMakeLists.txt |
| 136 | +CMakeLists.txt # Top-level CMakeLists.txt: project metadata and options |
| 137 | +CMakePresets.json # Presets for CMake, e.g. "release64", "debug64", etc. |
| 138 | +... |
| 139 | +``` |
| 140 | + |
| 141 | +As you can see, multiple `CMakeLists.txt` files exist within the project. Each |
| 142 | +one contains configurations relevant to the directory where it is stored. For |
| 143 | +example, the `tests/CMakeLists.txt` file configures unit tests using CMake. |
| 144 | + |
| 145 | +When modifying or extending this software, ensure that unit tests are added to |
| 146 | +cover your new code. In general, each C++ file in `src/` has a corresponding C++ |
| 147 | +file in `tests/` which implements unit tests. If you've added a new file in `tests/`, |
| 148 | +make sure to add that file to the executable in `tests/CMakeLists.txt`. |
| 149 | + |
| 150 | +To compile the software, from the cloned repository, run: |
| 151 | + |
| 152 | +```bash |
| 153 | +cmake -S . -B build |
| 154 | +cmake --build build |
| 155 | +``` |
| 156 | + |
| 157 | +After compiling the library, you can run unit tests as follows. First, change your |
| 158 | +working directory to the `build` directory, then run: |
| 159 | + |
| 160 | +```bash |
| 161 | +ctest |
| 162 | +``` |
| 163 | + |
| 164 | +The included `CMakePresets.json` provides presets for common CMake configurations. |
| 165 | +The "Release" configurations will compile the software with optimizations, build |
| 166 | +documentation, and configure unit tests. The "Debug" configurations will skip building |
| 167 | +the documentation, which is useful for rapid development and testing. Additionally, |
| 168 | +the Debug configuration will attempt to pass debug flags to the compiler. |
| 169 | + |
| 170 | +### Supported Platforms and Build Options |
| 171 | + |
| 172 | +The provided `CMakeLists.txt` and `CMakePresets.json` files aim to be flexible |
| 173 | +for development from the platform of your choosing. The approach taken is to make |
| 174 | +few assumptions about your toolchain to implicitly enable cross-platform and |
| 175 | +multi-environment development as much as possible. However, we cannnot guarantee |
| 176 | +that all compilers, tools, and platforms will work without requiring some additional |
| 177 | +configuration which is not documented here. If you find an issue or would like to |
| 178 | +see a change to support your chosen platform or tools, open an issue or create a |
| 179 | +pull request! |
| 180 | + |
| 181 | +## Documenting Code |
| 182 | + |
| 183 | +### C++ Base Libraries |
| 184 | + |
| 185 | +The C++ source code is documented with Doxygen. A GitHub Action is configured to |
| 186 | +build and deploy the documentation using GitHub Pages. This action will ensure |
| 187 | +that any new code has been accompanied by Doxygen-formatted documentation. Code |
| 188 | +will not be merged until and unless it is completely documented using Doxygen, |
| 189 | +and the GitHub action succesfully generates the documentation site. Below is an |
| 190 | +example showing the expected documentation formats. |
| 191 | + |
| 192 | +```cpp |
| 193 | +#define PI 3.1415 /**< Inline doxygen format, e.g. for macros or struct members */ |
| 194 | + |
| 195 | +/******************************************************************************* |
| 196 | + * This is a brief description of the function. |
| 197 | + * |
| 198 | + * This is an optional, longer description of the function. It can include |
| 199 | + * LaTeX formatting, for example: this function doubles its input @f$ x @f$ and |
| 200 | + * returns a value @f$ y @f$ with @f$ y = 2x @f$. |
| 201 | + * |
| 202 | + * @param[in] x The input and its expected units |
| 203 | + * @return The result @f$ y = 2x @f$ |
| 204 | + ******************************************************************************/ |
| 205 | +double doubleTheInput(double x) |
| 206 | +{ |
| 207 | + return 2 * x; |
| 208 | +} |
| 209 | +``` |
| 210 | +
|
| 211 | +### Python Wrappers |
| 212 | +
|
| 213 | +
|
| 214 | +
|
| 215 | +### C#/.NET Wrappers |
| 216 | +
|
| 217 | +### MATLAB Wrappers |
0 commit comments