| 
 | 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