|
| 1 | +# Contributing to Google Maps Driver Flutter Plugins |
| 2 | + |
| 3 | +_See also: [Flutter's code of conduct](https://flutter.io/design-principles/#code-of-conduct)_ |
| 4 | + |
| 5 | +## 1. Essential Setup for Contributors |
| 6 | + |
| 7 | +- **Operating System:** Linux, macOS, or Windows. |
| 8 | +- **Version Control:** [git](https://git-scm.com). |
| 9 | +- **Development Environment:** An IDE such as [Android Studio](https://developer.android.com/studio) or [Visual Studio Code](https://code.visualstudio.com/). |
| 10 | +- **Code Formatting:** [`swiftformat`](https://github.com/nicklockwood/SwiftFormat) (available via brew on macOS, on Windows install Swift toolchain and build SwiftFormat from git sources). |
| 11 | + |
| 12 | +### 1.1. Installing swiftformat |
| 13 | +The CI is locked to swiftformat 0.53 version which you can install with the command below: |
| 14 | +```bash |
| 15 | +curl -O https://raw.githubusercontent.com/Homebrew/homebrew-core/86f85aaa82beba49f8a5aabf3a22508c9249f188/Formula/s/swiftformat.rb |
| 16 | +brew install swiftformat.rb |
| 17 | +``` |
| 18 | + |
| 19 | +## 2. Setting Up Your Local Repository |
| 20 | + |
| 21 | +- **Preparation:** Before starting, make sure you have all dependencies installed as mentioned in the prior section. |
| 22 | +- **Fork the Repository:** Navigate to `https://github.com/googlemaps/flutter-driver-sdk` and create a fork in your GitHub account. |
| 23 | +- **SSH Key Configuration:** If your machine doesn't have an SSH key registered with GitHub, generate one following the instructions at [Generating SSH Keys on GitHub.](https://help.github.com/articles/generating-ssh-keys/). |
| 24 | +- **Clone Your Fork: ** Use the command `git clone [email protected]:<your_name_here>/flutter-driver-sdk.git` to clone the repository to your local machine. |
| 25 | +- **Add remote upstream: ** Establish a link to the main repository for updates using command `git remote add upstream [email protected]:googlemaps/flutter-driver-sdk.git` This ensures you pull changes from the original source, not just your clone, when using git fetch and similar commands. |
| 26 | + |
| 27 | +## 3. Install Melos |
| 28 | + |
| 29 | +This project leverages [Melos](https://github.com/invertase/melos) to manage the project and its dependencies. |
| 30 | + |
| 31 | +Run the following command to install Melos: |
| 32 | + |
| 33 | +```bash |
| 34 | +dart pub global activate melos |
| 35 | +``` |
| 36 | + |
| 37 | +## 4. Automatically generated MethodChannel with Pigeon |
| 38 | + |
| 39 | +### Using pigeon |
| 40 | + |
| 41 | +Google Maps Driver Flutter Plugins utilizes [pigeon](https://github.com/flutter/packages/tree/main/packages/pigeon) to generate the `MethodChannel` API layer between Dart and the native platforms. |
| 42 | +To modify the messages sent with Pigeon (i.e., the API code between Dart and native platforms), you can edit the `pigeons/messages.dart` file in the corresponding folder and regenerate the code by running the following melos command: |
| 43 | + |
| 44 | +``` |
| 45 | +melos run generate:pigeon |
| 46 | +``` |
| 47 | + |
| 48 | +Remember to format the generated files using the formatter. |
| 49 | + |
| 50 | +> [!NOTE] |
| 51 | +> The melos script automatically runs the formatter after pigeon generation. |
| 52 | +
|
| 53 | +### Testing pigeon generated code |
| 54 | + |
| 55 | +To test the created interface, you can mock the interface directly with: |
| 56 | + |
| 57 | +```dart |
| 58 | +late MockTestNAMEHostApi mockApi; |
| 59 | +TestNAMEHostApi.setup(mockApi); |
| 60 | +``` |
| 61 | + |
| 62 | +Add a unit test to a new method: |
| 63 | + |
| 64 | +1. Mock the return value (if the function has one). |
| 65 | + |
| 66 | +```dart |
| 67 | +when(mockApi.newMethod(any)).thenReturn(returnValueIn); |
| 68 | +``` |
| 69 | + |
| 70 | +3. Call the public API. |
| 71 | + |
| 72 | +```dart |
| 73 | +returnValueOut = await DeliveryDriver.newMethod(parameterIn) |
| 74 | +``` |
| 75 | + |
| 76 | +4. Check that the parameters and return values passed between the public API and platform match. |
| 77 | + |
| 78 | +```dart |
| 79 | +final VerificationResult result = verify(mockApi.newMethod(captureAny)); |
| 80 | +final MyType parameterOut = result.captured[0] as MyType; |
| 81 | +expect(parameterIn.param, parameterOut.param) |
| 82 | +expect(returnValueIn.param, returnValueOut.param) |
| 83 | +``` |
| 84 | + |
| 85 | +See examples in `test/` folders. |
| 86 | + |
| 87 | +## 5. Running the Driver Example |
| 88 | + |
| 89 | +The Google Maps Flutter Driver plugin provides an example app that showcases its main use-cases. |
| 90 | + |
| 91 | +To run the Driver example, navigate to the `example` directory of the plugin and run the app: |
| 92 | + |
| 93 | +```bash |
| 94 | +cd example |
| 95 | +flutter run --dart-define MAPS_API_KEY=YOUR_API_KEY --dart-define PROJECT_ID=YOUR_GOOGLE_CLOUD_PROJECT_ID |
| 96 | +``` |
| 97 | + |
| 98 | +## 6. Running tests |
| 99 | + |
| 100 | +Google Maps Flutter Driver package has integration and unit tests. |
| 101 | + |
| 102 | +### Unit tests |
| 103 | + |
| 104 | +To run unit tests for the Google Maps Flutter Driver plugin, navigate to the plugin's root directory and execute the `flutter test` command. Use the following command: |
| 105 | + |
| 106 | +```bash |
| 107 | +melos run test:dart |
| 108 | +``` |
| 109 | + |
| 110 | +To run unit tests on Android call |
| 111 | + |
| 112 | +```bash |
| 113 | +melos run test:android |
| 114 | +``` |
| 115 | + |
| 116 | +To run unit tests on iOS, follow these steps: |
| 117 | +1. Open Xcode. |
| 118 | +2. Navigate to the Test Navigator. |
| 119 | +3. Find and select the "RunnerTests" target. |
| 120 | +4. Click on the play icon button to run the tests. |
| 121 | + |
| 122 | +Or to run the iOS unit tests from command line, call |
| 123 | + |
| 124 | +```bash |
| 125 | +DEVICE='iPhone 15' melos run ios:test |
| 126 | +``` |
| 127 | + |
| 128 | +Specify the device you want to run the tests on with the DEVICE env variable. |
| 129 | + |
| 130 | +### Integration tests |
| 131 | + |
| 132 | +Integration tests are responsible for ensuring that the plugin works against the native Driver SDK for both Android and iOS platforms. Patrol is used for the integration tests to simplify interactions with native elements. To use patrol, you first need to activate the patrol_cli. |
| 133 | + |
| 134 | +```bash |
| 135 | +flutter pub global activate patrol_cli 2.5.0 |
| 136 | +``` |
| 137 | + |
| 138 | +To ensure that all necessary dependencies for patrol are properly set up, run the following command: |
| 139 | + |
| 140 | +```bash |
| 141 | +patrol doctor |
| 142 | +``` |
| 143 | + |
| 144 | +Google Maps Flutter Driver integration tests can be run with the following command: |
| 145 | + |
| 146 | +```bash |
| 147 | +cd ./example |
| 148 | +patrol test --dart-define MAPS_API_KEY=YOUR_API_KEY --dart-define PROJECT_ID=YOUR_GOOGLE_CLOUD_PROJECT_ID |
| 149 | +``` |
| 150 | + |
| 151 | +To only run a specific test file, use patrol command with -t flag. For example to run a plugin_integration_test.dart run it with the following command: |
| 152 | + |
| 153 | +```bash |
| 154 | +cd ./example |
| 155 | +patrol test --dart-define MAPS_API_KEY=YOUR_API_KEY --dart-define PROJECT_ID=YOUR_GOOGLE_CLOUD_PROJECT_ID -t integration_test/plugin_integration_test.dart |
| 156 | +``` |
| 157 | + |
| 158 | +Test report should appear in the build folder: |
| 159 | + |
| 160 | +``` |
| 161 | +Android - example/build/app/reports/androidTests/connected/debug/index.html |
| 162 | +iOS - example/build/ios_results_*.xcresult |
| 163 | +``` |
| 164 | + |
| 165 | +When adding new tests, add the location dialog and ToS check to the beginning of each test. |
| 166 | + |
| 167 | +```dart |
| 168 | + await checkLocationDialogAndTosAcceptance($); |
| 169 | +``` |
| 170 | + |
| 171 | +For debugging the tests, you can add `debugPrint()` functions in your test and use patrol develop mode with the `--verbose` flag to see the printed messages. To run `plugin_integration_test.dart` in develop mode, use the following command: |
| 172 | + |
| 173 | +```bash |
| 174 | +cd ./example |
| 175 | +patrol develop --dart-define MAPS_API_KEY=YOUR_API_KEY --dart-define PROJECT_ID=YOUR_GOOGLE_CLOUD_PROJECT_ID --verbose -t integration_test/plugin_integration_test.dart |
| 176 | +``` |
| 177 | + |
| 178 | +Please note that the "hot restart" feature in patrol's develop mode may not work correctly with all test files. |
| 179 | + |
| 180 | +#### Android emulator setup |
| 181 | + |
| 182 | +If the patrol tests fail to run on the Android emulator due to insufficient RAM, increase the emulator's default RAM allocation to ensure proper test execution. |
| 183 | + |
| 184 | +## 7. Contributing code |
| 185 | + |
| 186 | +We welcome contributions through GitHub pull requests. |
| 187 | + |
| 188 | +Before working on any significant changes, please review the [Flutter style guide](https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo) and [design principles](https://flutter.io/design-principles/). These guidelines help maintain code consistency and avoid common pitfalls. |
| 189 | + |
| 190 | +To begin working on a patch, follow these steps: |
| 191 | + |
| 192 | +1. Fetch the latest changes from the upstream repository: |
| 193 | + ```bash |
| 194 | + git fetch upstream |
| 195 | + ``` |
| 196 | + |
| 197 | +2. Create a new branch based on the latest upstream master branch: |
| 198 | + ```bash |
| 199 | + git checkout upstream/master -b <name_of_your_branch> |
| 200 | + ``` |
| 201 | + |
| 202 | +3. Start coding! |
| 203 | + |
| 204 | +Before committing your changes, it's important to ensure that your code passes the internal analyzer and formatting checks. You can run the following commands locally to identify any issues: |
| 205 | + |
| 206 | +- Run the analyze check: |
| 207 | + ```bash |
| 208 | + melos run flutter-analyze |
| 209 | + ``` |
| 210 | + |
| 211 | +- Format your code: |
| 212 | + ```bash |
| 213 | + melos run format |
| 214 | + ``` |
| 215 | + |
| 216 | +If you have made changes to pigeon messages, don't forget to generate the necessary code by running: |
| 217 | + |
| 218 | +```bash |
| 219 | +melos run generate:pigeon |
| 220 | +``` |
| 221 | + |
| 222 | +If you have changed files that have mocked tests, make sure to run the following command: |
| 223 | + |
| 224 | +```bash |
| 225 | +melos run generate:mocks |
| 226 | +``` |
| 227 | +And run affecting tests locally to make sure they still pass. |
| 228 | + |
| 229 | + |
| 230 | +Assuming all is successful, commit and push your code using the following commands: |
| 231 | + |
| 232 | +1. Stage your changes: |
| 233 | + ```bash |
| 234 | + git add . |
| 235 | + ``` |
| 236 | + |
| 237 | +2. Commit your changes with an informative commit message: |
| 238 | + ```bash |
| 239 | + git commit -m "<your informative commit message>" |
| 240 | + ``` |
| 241 | + |
| 242 | +3. Push your changes to the remote repository: |
| 243 | + ```bash |
| 244 | + git push origin <name_of_your_branch> |
| 245 | + ``` |
| 246 | + |
| 247 | +To send us a pull request: |
| 248 | + |
| 249 | +- `git pull-request` (if you are using [Hub](http://github.com/github/hub/)) or |
| 250 | + go to `https://github.com/googlemaps/flutter-driver-sdk` and click the |
| 251 | + "Compare & pull request" button |
| 252 | + |
| 253 | +Please ensure that all your commits have detailed commit messages explaining the changes made. |
| 254 | + |
| 255 | +When naming the title of your pull request, please follow the [Conventional Commits](https://www.conventionalcommits.org/en/v1.0.0-beta.4/) |
| 256 | +guide. For example, for a fix to the plugin: |
| 257 | + |
| 258 | +`fix: Fixed a bug!` |
| 259 | + |
| 260 | +Automated tests will be run on your contributions using GitHub Actions. Depending on |
| 261 | +your code changes, various tests will be performed automatically. |
| 262 | + |
| 263 | +Once you have received an LGTM (Looks Good To Me) from a project maintainer and once your pull request has passed all automated tests, please wait for one of the package maintainers to merge your changes. |
| 264 | + |
| 265 | +Before contributing, please ensure that you have completed the |
| 266 | +[Contributor License Agreement](https://cla.developers.google.com/clas). |
| 267 | +This can be done online and only takes a few moments. |
| 268 | +If you are submitting code for the first time, please add your (or your |
| 269 | +organization's) name and contact information to the [AUTHORS](AUTHORS) file. |
| 270 | + |
| 271 | +This project uses Google's `addlicense` [here](https://github.com/google/addlicense) tool to add the license header to all necessary files. Running `addlicense` is a required step before committing any new files. |
| 272 | + |
| 273 | +To install `addlicense`, run: |
| 274 | +```bash |
| 275 | +go install github.com/google/addlicense@latest |
| 276 | +``` |
| 277 | + |
| 278 | +Make sure to include `$HOME/go/bin` in your `PATH` environment variable. |
| 279 | +If you are using Bash on Linux or macOS, add `export PATH="$HOME/go/bin:$PATH"` to your `.bash_profile`. |
| 280 | + |
| 281 | +To add the license header to all files, run the following command from the root of the repository: |
| 282 | +```bash |
| 283 | +melos run add-license-header |
| 284 | +``` |
| 285 | +This command uses `addlicense` with all necessary flags. |
| 286 | + |
| 287 | +To check the license header of all files, run from the root of the repository: |
| 288 | +```bash |
| 289 | +melos run check-license-header |
| 290 | +``` |
| 291 | + |
| 292 | +## 8. Contributing documentation |
| 293 | + |
| 294 | +We welcome contributions to the plugin documentation. The documentation for this project is generated using Dart Docs. All documentation for the app-facing API is described in Dart files. |
| 295 | + |
| 296 | +Please refer to the "Contributing code" section above for instructions on how to prepare and submit a pull request to the repository. |
0 commit comments