|
| 1 | +> [!IMPORTANT] |
| 2 | +> All examples assume you are inside the repository root folder. |
| 3 | +
|
| 4 | + |
| 5 | +# Linting |
| 6 | + |
| 7 | +When contributing, ensure your changes to python code have a valid format. |
| 8 | + |
| 9 | +``` |
| 10 | +python -m pip install black |
| 11 | +black {source_file_or_directory} |
| 12 | +``` |
| 13 | + |
| 14 | +# Install package dependencies |
| 15 | + |
| 16 | +```shell |
| 17 | +python -m pip install --require-hashes -r hermetic_build/common/requirements.txt |
| 18 | +python -m pip install hermetic_build/common |
| 19 | +python -m pip install --require-hashes -r hermetic_build/library_generation/requirements.txt |
| 20 | +python -m pip install hermetic_build/library_generation |
| 21 | +python -m pip install --require-hashes -r hermetic_build/release_note_generation/requirements.txt |
| 22 | +python -m pip install hermetic_build/release_note_generation |
| 23 | +``` |
| 24 | + |
| 25 | +# Run the integration tests |
| 26 | + |
| 27 | +The integration tests build the docker image declared in |
| 28 | +`.cloudbuild/library_generation/library_generation.Dockerfile`, pull GAPIC |
| 29 | +repositories, generate the libraries and compare the results with the source |
| 30 | +code declared in a "golden branch" of the repo. |
| 31 | + |
| 32 | +It requires docker and python (>= 3.12.0) to be installed. |
| 33 | + |
| 34 | +```shell |
| 35 | +python -m unittest hermetic_build/library_generation/tests/integration_tests.py |
| 36 | +``` |
| 37 | + |
| 38 | +# Run the unit tests |
| 39 | + |
| 40 | +There is one unit test file per component. |
| 41 | +Every unit test script ends with `unit_tests.py`. |
| 42 | +To avoid specifying them individually, we can use the following command: |
| 43 | + |
| 44 | +```shell |
| 45 | +python -m unittest discover -s hermetic_build -p "*unit_tests.py" |
| 46 | +``` |
| 47 | + |
| 48 | +> [!NOTE] |
| 49 | +> The output of this command may look erratic during the first 30 seconds. |
| 50 | +> This is normal. After the tests are done, an "OK" message should be shown. |
| 51 | +
|
| 52 | +# Run the library generation scripts in your local environment |
| 53 | + |
| 54 | +Although the scripts are designed to run in a Docker container, you can also |
| 55 | +run them directly. |
| 56 | +This section explains how to run the entrypoint script |
| 57 | +(`hermetic_build/library_generation/cli/entry_point.py`). |
| 58 | + |
| 59 | +## Assumptions made by the scripts |
| 60 | + |
| 61 | +### The Hermetic Build's well-known folder |
| 62 | +Located in `${HOME}/.library_generation`, this folder is assumed by the scripts |
| 63 | +to contain certain tools. |
| 64 | + |
| 65 | +Developers must make sure this folder is properly configured before running the |
| 66 | +scripts locally. |
| 67 | +Note that this relies on the `HOME` environment variable which is always defined |
| 68 | +as per [POSIX env var definition](https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap08.html). |
| 69 | + |
| 70 | +#### Put the gapic-generator-java jar in its well-known location |
| 71 | + |
| 72 | +1. Run the following command to install gapic-generator-java. |
| 73 | + |
| 74 | + ```shell |
| 75 | + mvn install -B -ntp -DskipTests -Dclirr.skip -Dcheckstyle.skip |
| 76 | + ``` |
| 77 | + This will generate a jar located in `~/.m2/repository/com/google/api/gapic-generator-java/{version}/gapic-generator-java-{version}.jar` |
| 78 | + |
| 79 | +2. Move the jar into its well-known location. |
| 80 | + |
| 81 | + ```shell |
| 82 | + mv /path/to/jar "${HOME}/.library_generation/gapic-generator-java.jar" |
| 83 | + ``` |
| 84 | + |
| 85 | +#### Put the java formatter jar in its well-known location |
| 86 | + |
| 87 | +1. Download google-java-format-{version}-all-deps.jar from [Maven Central](https://central.sonatype.com/artifact/com.google.googlejavaformat/google-java-format) |
| 88 | +or [GitHub releases](https://github.com/google/google-java-format/releases). |
| 89 | +2. Move the jar into its well-known location. |
| 90 | + |
| 91 | + ```shell |
| 92 | + mv /path/to/jar "${HOME}/.library_generation/google-java-format.jar" |
| 93 | + ``` |
| 94 | + |
| 95 | +## Installing prerequisites |
| 96 | + |
| 97 | +In order to run the generation scripts directly, there are a few tools we |
| 98 | +need to install beforehand. |
| 99 | + |
| 100 | +### Install the owl-bot CLI |
| 101 | + |
| 102 | +This requires node.js to be installed. |
| 103 | +Check this [installation guide](https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script) |
| 104 | +for NVM, Node.js's version manager. |
| 105 | + |
| 106 | +After you install it, you can install the owl-bot CLI with the following |
| 107 | +commands: |
| 108 | + |
| 109 | +```shell |
| 110 | +git clone https://github.com/googleapis/repo-automation-bots |
| 111 | +cd repo-automation-bots/packages/owl-bot |
| 112 | +npm i && npm run compile && npm link |
| 113 | +owl-bot copy-code --version |
| 114 | +``` |
| 115 | + |
| 116 | +The key step is `npm link`, which will make the command available in you current |
| 117 | +shell session. |
| 118 | + |
| 119 | +## Run the script |
| 120 | +The entrypoint script (`hermetic_build/library_generation/cli/entry_point.py`) |
| 121 | +allows you to generate a GAPIC repository with a given api definition (proto, |
| 122 | +service yaml). |
| 123 | + |
| 124 | +### Download the api definition |
| 125 | +For example, from googleapis |
| 126 | + |
| 127 | +```shell |
| 128 | +git clone https://github.com/googleapis/googleapis |
| 129 | +export api_definitions_path="$(pwd)/googleapis" |
| 130 | +``` |
| 131 | + |
| 132 | +### Download the repo |
| 133 | +For example, google-cloud-java |
| 134 | +```shell |
| 135 | +git clone https://github.com/googleapis/google-cloud-java |
| 136 | +export path_to_repo="$(pwd)/google-cloud-java" |
| 137 | +``` |
| 138 | + |
| 139 | +### Install the scripts |
| 140 | + |
| 141 | +You can skip this step if you've installed the packages in [Install package dependencies](#install-package-dependencies). |
| 142 | + |
| 143 | +```shell |
| 144 | +python -m pip install --require-hashes -r hermetic_build/common/requirements.txt |
| 145 | +python -m pip install hermetic_build/common |
| 146 | +python -m pip install --require-hashes -r hermetic_build/library_generation/requirements.txt |
| 147 | +python -m pip install hermetic_build/library_generation |
| 148 | +``` |
| 149 | + |
| 150 | +### Run the script |
| 151 | + |
| 152 | +```shell |
| 153 | +python hermetic_build/library_generation/cli/entry_point.py generate \ |
| 154 | + --repository-path="${path_to_repo}" \ |
| 155 | + --api-definitions-path="${api_definitions_path}" |
| 156 | +``` |
| 157 | + |
| 158 | +# Build the image from source |
| 159 | + |
| 160 | +1. Run the following command to build the image from source |
| 161 | + |
| 162 | + ```shell |
| 163 | + docker build \ |
| 164 | + -f .cloudbuild/library_generation/library_generation.Dockerfile \ |
| 165 | + -t local:image-tag \ |
| 166 | + . |
| 167 | + ``` |
| 168 | + |
| 169 | +2. Set the version of gapic-generator-java |
| 170 | + |
| 171 | + ```shell |
| 172 | + LOCAL_GENERATOR_VERSION=$(mvn \ |
| 173 | + org.apache.maven.plugins:maven-help-plugin:evaluate \ |
| 174 | + -Dexpression=project.version \ |
| 175 | + -pl gapic-generator-java \ |
| 176 | + -DforceStdout \ |
| 177 | + -q) |
| 178 | + ``` |
| 179 | + |
| 180 | +3. Run the image |
| 181 | + |
| 182 | + ```shell |
| 183 | + # Assume you want to generate the library in the current working directory |
| 184 | + # and the generation configuration is in the same directory. |
| 185 | + docker run \ |
| 186 | + --rm \ |
| 187 | + --quiet \ |
| 188 | + -u "$(id -u):$(id -g)" \ |
| 189 | + -v "$(pwd):/workspace" \ |
| 190 | + -v /path/to/api-definitions:/workspace/apis \ |
| 191 | + -e GENERATOR_VERSION="${LOCAL_GENERATOR_VERSION}" \ |
| 192 | + local:image-tag \ |
| 193 | + --generation-config-path=/workspace/generation_config_file \ |
| 194 | + --library-names=apigee-connect,asset \ |
| 195 | + --repository-path=/workspace \ |
| 196 | + --api-definitions-path=/workspace/apis |
| 197 | + ``` |
| 198 | + Note that if you specify the generator version using environment variable, |
| 199 | + `-e GENERATOR_VERSION="${LOCAL_GENERATOR_VERSION}"` in the above example, |
| 200 | + you should not set `gapic_generator_version` and `protoc_version` in the |
| 201 | + generation configuration because values in the generation configuration will |
| 202 | + take precedence. |
| 203 | + |
| 204 | +# Debug the library generation container |
| 205 | +If you are working on changing the way the containers are created, you may want |
| 206 | +to inspect the containers to check the setup. |
| 207 | +It would be convenient in such case to have a text editor/viewer available. |
| 208 | +You can achieve this by modifying the Dockerfile as follows: |
| 209 | + |
| 210 | +```dockerfile |
| 211 | +# install OS tools |
| 212 | +RUN apk update && apk add \ |
| 213 | + unzip curl rsync openjdk11 jq bash nodejs npm git less vim |
| 214 | +``` |
| 215 | + |
| 216 | +We add `less` and `vim` as text tools for further inspection. |
| 217 | + |
| 218 | +You can also run a shell in a new container by running: |
| 219 | + |
| 220 | +```shell |
| 221 | +docker run \ |
| 222 | + --rm \ |
| 223 | + -it \ |
| 224 | + -u $(id -u):$(id -g) \ |
| 225 | + -v /path/to/google-cloud-java:/workspace \ |
| 226 | + --entrypoint="bash" \ |
| 227 | + $(cat image-id) |
| 228 | +``` |
0 commit comments