├── .github ├── CODEOWNERS ├── release-please.yml ├── release-trigger.yml ├── sync-repo-settings.yaml └── workflows │ ├── ci.yml │ └── release-please-now.yml ├── .gitignore ├── .kokoro ├── populate-secrets.sh ├── release.cfg ├── release.sh └── trampoline_v2.sh ├── .release-please-manifest.json ├── .rubocop.yml ├── .toys └── .toys.rb ├── .trampolinerc ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Gemfile ├── LICENSE ├── README.md ├── SECURITY.md ├── google-style.gemspec ├── google-style.yml ├── lib └── google │ └── style │ └── version.rb ├── release-please-config.json └── renovate.json /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Code owners file. 2 | # This file controls who is tagged for review for any given pull request. 3 | # 4 | # For syntax help see: 5 | # https://help.github.com/en/github/creating-cloning-and-archiving-repositories/about-code-owners#codeowners-syntax 6 | 7 | * @googleapis/ruby-team 8 | -------------------------------------------------------------------------------- /.github/release-please.yml: -------------------------------------------------------------------------------- 1 | bumpMinorPreMajor: true 2 | handleGHRelease: true 3 | manifest: true 4 | monorepoTags: true 5 | packageName: google-style 6 | primaryBranch: main 7 | releaseType: ruby-yoshi 8 | -------------------------------------------------------------------------------- /.github/release-trigger.yml: -------------------------------------------------------------------------------- 1 | enabled: true 2 | -------------------------------------------------------------------------------- /.github/sync-repo-settings.yaml: -------------------------------------------------------------------------------- 1 | rebaseMergeAllowed: true 2 | squashMergeAllowed: true 3 | mergeCommitAllowed: false 4 | branchProtectionRules: 5 | - pattern: main 6 | isAdminEnforced: false 7 | requiredStatusCheckContexts: 8 | - 'cla/google' 9 | requiredApprovingReviewCount: 1 10 | requiresCodeOwnerReviews: true 11 | requiresStrictStatusChecks: true 12 | permissionRules: 13 | - team: yoshi-admins 14 | permission: admin 15 | - team: ruby-admins 16 | permission: admin 17 | - team: ruby-team 18 | permission: push 19 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: CI 2 | on: 3 | pull_request: 4 | branches: 5 | - main 6 | push: 7 | branches: 8 | - main 9 | workflow_dispatch: 10 | jobs: 11 | CI: 12 | if: ${{ github.repository == 'googleapis/ruby-style' }} 13 | strategy: 14 | matrix: 15 | include: 16 | - os: ubuntu-latest 17 | ruby: "3.1" 18 | - os: ubuntu-latest 19 | ruby: "3.2" 20 | - os: ubuntu-latest 21 | ruby: "3.3" 22 | - os: ubuntu-latest 23 | ruby: "3.4" 24 | fail-fast: false 25 | runs-on: ${{ matrix.os }} 26 | steps: 27 | - name: Checkout repo 28 | uses: actions/checkout@v4 29 | - name: Install Ruby ${{ matrix.ruby }} 30 | uses: ruby/setup-ruby@v1 31 | with: 32 | ruby-version: "${{ matrix.ruby }}" 33 | - name: Install tools 34 | shell: bash 35 | run: "bundle install && gem install --no-document toys" 36 | - name: Test 37 | shell: bash 38 | run: toys rubocop < /dev/null 39 | -------------------------------------------------------------------------------- /.github/workflows/release-please-now.yml: -------------------------------------------------------------------------------- 1 | name: Release-Please Now 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | args: 6 | description: "Extra command line arguments." 7 | required: false 8 | 9 | jobs: 10 | add-release-please-label: 11 | if: ${{ github.repository == 'googleapis/ruby-style' }} 12 | runs-on: ubuntu-latest 13 | env: 14 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 15 | RELEASE_PLEASE_DISABLE: ${{ secrets.RELEASE_PLEASE_DISABLE }} 16 | steps: 17 | - name: Checkout repo 18 | uses: actions/checkout@v4 19 | - name: Install Ruby 3.3 20 | uses: ruby/setup-ruby@v1 21 | with: 22 | ruby-version: "3.3" 23 | - name: Install tools 24 | run: | 25 | gem install --no-document toys 26 | - name: execute 27 | run: | 28 | toys release label-please -v \ 29 | --github-event-name=${{ github.event_name }} \ 30 | ${{ github.event.inputs.args }} 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.bundle/ 2 | /pkg/ 3 | .DS_Store 4 | *.gem 5 | Gemfile.lock 6 | /node_modules/ 7 | /package-lock.json 8 | -------------------------------------------------------------------------------- /.kokoro/populate-secrets.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Copyright 2021 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | # This file is called in the early stage of `trampoline_v2.sh` to 18 | # populate secrets needed for the CI builds. 19 | 20 | set -eo pipefail 21 | 22 | function now { date +"%Y-%m-%d %H:%M:%S" | tr -d '\n' ;} 23 | function msg { println "$*" >&2 ;} 24 | function println { printf '%s\n' "$(now) $*" ;} 25 | 26 | # Populates requested secrets set in SECRET_MANAGER_KEYS 27 | if [[ -z "${SECRET_MANAGER_PROJECT_ID-}" ]]; then 28 | msg "SECRET_MANAGER_PROJECT_ID is not set in environment variables, using default" 29 | SECRET_MANAGER_PROJECT_ID="cloud-devrel-kokoro-resources" 30 | fi 31 | 32 | # In Kokoro CI builds, we use the service account attached to the 33 | # Kokoro VM. This means we need to setup auth on other CI systems. 34 | # For local run, we just use the gcloud command for retrieving the 35 | # secrets. 36 | 37 | if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then 38 | GCLOUD_COMMANDS=( 39 | "docker" 40 | "run" 41 | "--entrypoint=gcloud" 42 | "--volume=${KOKORO_GFILE_DIR}:${KOKORO_GFILE_DIR}" 43 | "gcr.io/google.com/cloudsdktool/cloud-sdk" 44 | ) 45 | if [[ "${TRAMPOLINE_CI:-}" == "kokoro" ]]; then 46 | SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager" 47 | else 48 | echo "Authentication for this CI system is not implemented yet." 49 | exit 2 50 | # TODO: Determine appropriate SECRET_LOCATION and the GCLOUD_COMMANDS. 51 | fi 52 | else 53 | # For local run, use /dev/shm or temporary directory for 54 | # KOKORO_GFILE_DIR. 55 | if [[ -d "/dev/shm" ]]; then 56 | export KOKORO_GFILE_DIR=/dev/shm 57 | else 58 | export KOKORO_GFILE_DIR=$(mktemp -d -t ci-XXXXXXXX) 59 | fi 60 | SECRET_LOCATION="${KOKORO_GFILE_DIR}/secret_manager" 61 | GCLOUD_COMMANDS=("gcloud") 62 | fi 63 | 64 | msg "Creating folder on disk for secrets: ${SECRET_LOCATION}" 65 | mkdir -p ${SECRET_LOCATION} 66 | 67 | for key in $(echo ${SECRET_MANAGER_KEYS} | sed "s/,/ /g") 68 | do 69 | msg "Retrieving secret ${key}" 70 | "${GCLOUD_COMMANDS[@]}" \ 71 | secrets versions access latest \ 72 | --project "${SECRET_MANAGER_PROJECT_ID}" \ 73 | --secret $key > \ 74 | "$SECRET_LOCATION/$key" 75 | if [[ $? == 0 ]]; then 76 | msg "Secret written to ${SECRET_LOCATION}/${key}" 77 | else 78 | msg "Error retrieving secret ${key}" 79 | exit 2 80 | fi 81 | done 82 | -------------------------------------------------------------------------------- /.kokoro/release.cfg: -------------------------------------------------------------------------------- 1 | # Format: //devtools/kokoro/config/proto/build.proto 2 | 3 | # Build logs will be here 4 | action { 5 | define_artifacts { 6 | regex: "**/*sponge_log.xml" 7 | } 8 | } 9 | 10 | # Use the trampoline script to run in docker. 11 | build_file: "ruby-style/.kokoro/trampoline_v2.sh" 12 | 13 | # Configure the docker image for kokoro-trampoline. 14 | env_vars: { 15 | key: "TRAMPOLINE_IMAGE" 16 | value: "us-central1-docker.pkg.dev/cloud-sdk-release-custom-pool/release-images/ruby-release" 17 | } 18 | 19 | env_vars: { 20 | key: "TRAMPOLINE_BUILD_FILE" 21 | value: ".kokoro/release.sh" 22 | } 23 | 24 | env_vars: { 25 | key: "SECRET_MANAGER_PROJECT_ID" 26 | value: "cloud-sdk-release-custom-pool" 27 | } 28 | 29 | env_vars: { 30 | key: "SECRET_MANAGER_KEYS" 31 | value: "releasetool-publish-reporter-app,releasetool-publish-reporter-googleapis-installation,releasetool-publish-reporter-pem" 32 | } 33 | 34 | # Pick up Rubygems key from internal keystore 35 | before_action { 36 | fetch_keystore { 37 | keystore_resource { 38 | keystore_config_id: 73713 39 | keyname: "rubygems-publish-key" 40 | backend: "blade:keystore-fastconfigpush" 41 | } 42 | } 43 | } 44 | 45 | # Store the packages uploaded to rubygems.org, which 46 | # we can later use to generate SBOMs and attestations. 47 | action { 48 | define_artifacts { 49 | regex: "github/ruby-style/pkg/*.gem" 50 | strip_prefix: "github" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /.kokoro/release.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -eo pipefail 4 | 5 | # Install gems in the user directory because the default install directory 6 | # is in a read-only location. 7 | export GEM_HOME=$HOME/.gem 8 | export PATH=$GEM_HOME/bin:$PATH 9 | 10 | toys release perform -v --reporter-org=googleapis < /dev/null 11 | -------------------------------------------------------------------------------- /.kokoro/trampoline_v2.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Copyright 2020 Google LLC 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | 16 | # trampoline_v2.sh 17 | # 18 | # If you want to make a change to this file, consider doing so at: 19 | # https://github.com/googlecloudplatform/docker-ci-helper 20 | # 21 | # This script is for running CI builds. For Kokoro builds, we 22 | # set this script to `build_file` field in the Kokoro configuration. 23 | 24 | # This script does 3 things. 25 | # 26 | # 1. Prepare the Docker image for the test 27 | # 2. Run the Docker with appropriate flags to run the test 28 | # 3. Upload the newly built Docker image 29 | # 30 | # in a way that is somewhat compatible with trampoline_v1. 31 | # 32 | # These environment variables are required: 33 | # TRAMPOLINE_IMAGE: The docker image to use. 34 | # TRAMPOLINE_DOCKERFILE: The location of the Dockerfile. 35 | # 36 | # You can optionally change these environment variables: 37 | # TRAMPOLINE_IMAGE_UPLOAD: 38 | # (true|false): Whether to upload the Docker image after the 39 | # successful builds. 40 | # TRAMPOLINE_BUILD_FILE: The script to run in the docker container. 41 | # TRAMPOLINE_WORKSPACE: The workspace path in the docker container. 42 | # Defaults to /workspace. 43 | # Potentially there are some repo specific envvars in .trampolinerc in 44 | # the project root. 45 | # 46 | # Here is an example for running this script. 47 | # TRAMPOLINE_IMAGE=gcr.io/cloud-devrel-kokoro-resources/node:10-user \ 48 | # TRAMPOLINE_BUILD_FILE=.kokoro/system-test.sh \ 49 | # .kokoro/trampoline_v2.sh 50 | 51 | set -euo pipefail 52 | 53 | TRAMPOLINE_VERSION="2.0.10" 54 | 55 | if command -v tput >/dev/null && [[ -n "${TERM:-}" ]]; then 56 | readonly IO_COLOR_RED="$(tput setaf 1)" 57 | readonly IO_COLOR_GREEN="$(tput setaf 2)" 58 | readonly IO_COLOR_YELLOW="$(tput setaf 3)" 59 | readonly IO_COLOR_RESET="$(tput sgr0)" 60 | else 61 | readonly IO_COLOR_RED="" 62 | readonly IO_COLOR_GREEN="" 63 | readonly IO_COLOR_YELLOW="" 64 | readonly IO_COLOR_RESET="" 65 | fi 66 | 67 | function function_exists { 68 | [ $(LC_ALL=C type -t $1)"" == "function" ] 69 | } 70 | 71 | # Logs a message using the given color. The first argument must be one 72 | # of the IO_COLOR_* variables defined above, such as 73 | # "${IO_COLOR_YELLOW}". The remaining arguments will be logged in the 74 | # given color. The log message will also have an RFC-3339 timestamp 75 | # prepended (in UTC). You can disable the color output by setting 76 | # TERM=vt100. 77 | function log_impl() { 78 | local color="$1" 79 | shift 80 | local timestamp="$(date -u "+%Y-%m-%dT%H:%M:%SZ")" 81 | echo "================================================================" 82 | echo "${color}${timestamp}:" "$@" "${IO_COLOR_RESET}" 83 | echo "================================================================" 84 | } 85 | 86 | # Logs the given message with normal coloring and a timestamp. 87 | function log() { 88 | log_impl "${IO_COLOR_RESET}" "$@" 89 | } 90 | 91 | # Logs the given message in green with a timestamp. 92 | function log_green() { 93 | log_impl "${IO_COLOR_GREEN}" "$@" 94 | } 95 | 96 | # Logs the given message in yellow with a timestamp. 97 | function log_yellow() { 98 | log_impl "${IO_COLOR_YELLOW}" "$@" 99 | } 100 | 101 | # Logs the given message in red with a timestamp. 102 | function log_red() { 103 | log_impl "${IO_COLOR_RED}" "$@" 104 | } 105 | 106 | readonly tmpdir=$(mktemp -d -t ci-XXXXXXXX) 107 | readonly tmphome="${tmpdir}/h" 108 | mkdir -p "${tmphome}" 109 | 110 | function cleanup() { 111 | rm -rf "${tmpdir}" 112 | } 113 | trap cleanup EXIT 114 | 115 | RUNNING_IN_CI="${RUNNING_IN_CI:-false}" 116 | 117 | # The workspace in the container, defaults to /workspace. 118 | TRAMPOLINE_WORKSPACE="${TRAMPOLINE_WORKSPACE:-/workspace}" 119 | 120 | pass_down_envvars=( 121 | # TRAMPOLINE_V2 variables. 122 | # Tells scripts whether they are running as part of CI or not. 123 | "RUNNING_IN_CI" 124 | # Indicates which CI system we're in. 125 | "TRAMPOLINE_CI" 126 | # Indicates the version of the script. 127 | "TRAMPOLINE_VERSION" 128 | ) 129 | 130 | log_yellow "Building with Trampoline ${TRAMPOLINE_VERSION}" 131 | 132 | # Detect which CI systems we're in. If we're in any of the CI systems 133 | # we support, `RUNNING_IN_CI` will be true and `TRAMPOLINE_CI` will be 134 | # the name of the CI system. Both envvars will be passing down to the 135 | # container for telling which CI system we're in. 136 | if [[ -n "${KOKORO_BUILD_ID:-}" ]]; then 137 | # descriptive env var for indicating it's on CI. 138 | RUNNING_IN_CI="true" 139 | TRAMPOLINE_CI="kokoro" 140 | if [[ "${TRAMPOLINE_USE_LEGACY_SERVICE_ACCOUNT:-}" == "true" ]]; then 141 | if [[ ! -f "${KOKORO_GFILE_DIR}/kokoro-trampoline.service-account.json" ]]; then 142 | log_red "${KOKORO_GFILE_DIR}/kokoro-trampoline.service-account.json does not exist. Did you forget to mount cloud-devrel-kokoro-resources/trampoline? Aborting." 143 | exit 1 144 | fi 145 | # This service account will be activated later. 146 | TRAMPOLINE_SERVICE_ACCOUNT="${KOKORO_GFILE_DIR}/kokoro-trampoline.service-account.json" 147 | else 148 | if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then 149 | gcloud auth list 150 | fi 151 | log_yellow "Configuring Container Registry access" 152 | TRAMPOLINE_HOST=$(echo "${TRAMPOLINE_IMAGE}" | cut -d/ -f1) 153 | if [[ ! "${TRAMPOLINE_HOST}" =~ "gcr.io" ]]; then 154 | # If you need to specificy a host other than gcr.io, you have to run on an update version of gcloud. 155 | echo "TRAMPOLINE_HOST: ${TRAMPOLINE_HOST}" 156 | gcloud components update 157 | gcloud auth configure-docker "${TRAMPOLINE_HOST}" 158 | else 159 | gcloud auth configure-docker --quiet 160 | fi 161 | fi 162 | pass_down_envvars+=( 163 | # KOKORO dynamic variables. 164 | "KOKORO_BUILD_NUMBER" 165 | "KOKORO_BUILD_ID" 166 | "KOKORO_JOB_NAME" 167 | "KOKORO_GIT_COMMIT" 168 | "KOKORO_GITHUB_COMMIT" 169 | "KOKORO_GITHUB_PULL_REQUEST_NUMBER" 170 | "KOKORO_GITHUB_PULL_REQUEST_COMMIT" 171 | # For Flaky Bot 172 | "KOKORO_GITHUB_COMMIT_URL" 173 | "KOKORO_GITHUB_PULL_REQUEST_URL" 174 | "KOKORO_BUILD_ARTIFACTS_SUBDIR" 175 | ) 176 | elif [[ "${TRAVIS:-}" == "true" ]]; then 177 | RUNNING_IN_CI="true" 178 | TRAMPOLINE_CI="travis" 179 | pass_down_envvars+=( 180 | "TRAVIS_BRANCH" 181 | "TRAVIS_BUILD_ID" 182 | "TRAVIS_BUILD_NUMBER" 183 | "TRAVIS_BUILD_WEB_URL" 184 | "TRAVIS_COMMIT" 185 | "TRAVIS_COMMIT_MESSAGE" 186 | "TRAVIS_COMMIT_RANGE" 187 | "TRAVIS_JOB_NAME" 188 | "TRAVIS_JOB_NUMBER" 189 | "TRAVIS_JOB_WEB_URL" 190 | "TRAVIS_PULL_REQUEST" 191 | "TRAVIS_PULL_REQUEST_BRANCH" 192 | "TRAVIS_PULL_REQUEST_SHA" 193 | "TRAVIS_PULL_REQUEST_SLUG" 194 | "TRAVIS_REPO_SLUG" 195 | "TRAVIS_SECURE_ENV_VARS" 196 | "TRAVIS_TAG" 197 | ) 198 | elif [[ -n "${GITHUB_RUN_ID:-}" ]]; then 199 | RUNNING_IN_CI="true" 200 | TRAMPOLINE_CI="github-workflow" 201 | pass_down_envvars+=( 202 | "GITHUB_WORKFLOW" 203 | "GITHUB_RUN_ID" 204 | "GITHUB_RUN_NUMBER" 205 | "GITHUB_ACTION" 206 | "GITHUB_ACTIONS" 207 | "GITHUB_ACTOR" 208 | "GITHUB_REPOSITORY" 209 | "GITHUB_EVENT_NAME" 210 | "GITHUB_EVENT_PATH" 211 | "GITHUB_SHA" 212 | "GITHUB_REF" 213 | "GITHUB_HEAD_REF" 214 | "GITHUB_BASE_REF" 215 | ) 216 | elif [[ "${CIRCLECI:-}" == "true" ]]; then 217 | RUNNING_IN_CI="true" 218 | TRAMPOLINE_CI="circleci" 219 | pass_down_envvars+=( 220 | "CIRCLE_BRANCH" 221 | "CIRCLE_BUILD_NUM" 222 | "CIRCLE_BUILD_URL" 223 | "CIRCLE_COMPARE_URL" 224 | "CIRCLE_JOB" 225 | "CIRCLE_NODE_INDEX" 226 | "CIRCLE_NODE_TOTAL" 227 | "CIRCLE_PREVIOUS_BUILD_NUM" 228 | "CIRCLE_PROJECT_REPONAME" 229 | "CIRCLE_PROJECT_USERNAME" 230 | "CIRCLE_REPOSITORY_URL" 231 | "CIRCLE_SHA1" 232 | "CIRCLE_STAGE" 233 | "CIRCLE_USERNAME" 234 | "CIRCLE_WORKFLOW_ID" 235 | "CIRCLE_WORKFLOW_JOB_ID" 236 | "CIRCLE_WORKFLOW_UPSTREAM_JOB_IDS" 237 | "CIRCLE_WORKFLOW_WORKSPACE_ID" 238 | ) 239 | fi 240 | 241 | # Configure the service account for pulling the docker image. 242 | function repo_root() { 243 | local dir="$1" 244 | while [[ ! -d "${dir}/.git" ]]; do 245 | dir="$(dirname "$dir")" 246 | done 247 | echo "${dir}" 248 | } 249 | 250 | # Detect the project root. In CI builds, we assume the script is in 251 | # the git tree and traverse from there, otherwise, traverse from `pwd` 252 | # to find `.git` directory. 253 | if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then 254 | PROGRAM_PATH="$(realpath "$0")" 255 | PROGRAM_DIR="$(dirname "${PROGRAM_PATH}")" 256 | PROJECT_ROOT="$(repo_root "${PROGRAM_DIR}")" 257 | else 258 | PROJECT_ROOT="$(repo_root $(pwd))" 259 | fi 260 | 261 | log_yellow "Changing to the project root: ${PROJECT_ROOT}." 262 | cd "${PROJECT_ROOT}" 263 | 264 | # To support relative path for `TRAMPOLINE_SERVICE_ACCOUNT`, we need 265 | # to use this environment variable in `PROJECT_ROOT`. 266 | if [[ -n "${TRAMPOLINE_SERVICE_ACCOUNT:-}" ]]; then 267 | 268 | mkdir -p "${tmpdir}/gcloud" 269 | gcloud_config_dir="${tmpdir}/gcloud" 270 | 271 | log_yellow "Using isolated gcloud config: ${gcloud_config_dir}." 272 | export CLOUDSDK_CONFIG="${gcloud_config_dir}" 273 | 274 | log_yellow "Using ${TRAMPOLINE_SERVICE_ACCOUNT} for authentication." 275 | gcloud auth activate-service-account \ 276 | --key-file "${TRAMPOLINE_SERVICE_ACCOUNT}" 277 | log_yellow "Configuring Container Registry access" 278 | gcloud auth configure-docker --quiet 279 | fi 280 | 281 | required_envvars=( 282 | # The basic trampoline configurations. 283 | "TRAMPOLINE_IMAGE" 284 | "TRAMPOLINE_BUILD_FILE" 285 | ) 286 | 287 | if [[ -f "${PROJECT_ROOT}/.trampolinerc" ]]; then 288 | source "${PROJECT_ROOT}/.trampolinerc" 289 | fi 290 | 291 | log_yellow "Checking environment variables." 292 | for e in "${required_envvars[@]}" 293 | do 294 | if [[ -z "${!e:-}" ]]; then 295 | log "Missing ${e} env var. Aborting." 296 | exit 1 297 | fi 298 | done 299 | 300 | # We want to support legacy style TRAMPOLINE_BUILD_FILE used with V1 301 | # script: e.g. "github/repo-name/.kokoro/run_tests.sh" 302 | TRAMPOLINE_BUILD_FILE="${TRAMPOLINE_BUILD_FILE#github/*/}" 303 | log_yellow "Using TRAMPOLINE_BUILD_FILE: ${TRAMPOLINE_BUILD_FILE}" 304 | 305 | # ignore error on docker operations and test execution 306 | set +e 307 | 308 | log_yellow "Preparing Docker image." 309 | # We only download the docker image in CI builds. 310 | if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then 311 | # Download the docker image specified by `TRAMPOLINE_IMAGE` 312 | 313 | # We may want to add --max-concurrent-downloads flag. 314 | 315 | log_yellow "Start pulling the Docker image: ${TRAMPOLINE_IMAGE}." 316 | if docker pull "${TRAMPOLINE_IMAGE}"; then 317 | log_green "Finished pulling the Docker image: ${TRAMPOLINE_IMAGE}." 318 | has_image="true" 319 | else 320 | log_red "Failed pulling the Docker image: ${TRAMPOLINE_IMAGE}." 321 | has_image="false" 322 | fi 323 | else 324 | # For local run, check if we have the image. 325 | if docker images "${TRAMPOLINE_IMAGE}" | grep "${TRAMPOLINE_IMAGE%:*}"; then 326 | has_image="true" 327 | else 328 | has_image="false" 329 | fi 330 | fi 331 | 332 | 333 | # The default user for a Docker container has uid 0 (root). To avoid 334 | # creating root-owned files in the build directory we tell docker to 335 | # use the current user ID. 336 | user_uid="$(id -u)" 337 | user_gid="$(id -g)" 338 | user_name="$(id -un)" 339 | 340 | # To allow docker in docker, we add the user to the docker group in 341 | # the host os. 342 | docker_gid=$(cut -d: -f3 < <(getent group docker)) 343 | 344 | update_cache="false" 345 | if [[ "${TRAMPOLINE_DOCKERFILE:-none}" != "none" ]]; then 346 | # Build the Docker image from the source. 347 | context_dir=$(dirname "${TRAMPOLINE_DOCKERFILE}") 348 | docker_build_flags=( 349 | "-f" "${TRAMPOLINE_DOCKERFILE}" 350 | "-t" "${TRAMPOLINE_IMAGE}" 351 | "--build-arg" "UID=${user_uid}" 352 | "--build-arg" "USERNAME=${user_name}" 353 | ) 354 | if [[ "${has_image}" == "true" ]]; then 355 | docker_build_flags+=("--cache-from" "${TRAMPOLINE_IMAGE}") 356 | fi 357 | 358 | log_yellow "Start building the docker image." 359 | if [[ "${TRAMPOLINE_VERBOSE:-false}" == "true" ]]; then 360 | echo "docker build" "${docker_build_flags[@]}" "${context_dir}" 361 | fi 362 | 363 | # ON CI systems, we want to suppress docker build logs, only 364 | # output the logs when it fails. 365 | if [[ "${RUNNING_IN_CI:-}" == "true" ]]; then 366 | if docker build "${docker_build_flags[@]}" "${context_dir}" \ 367 | > "${tmpdir}/docker_build.log" 2>&1; then 368 | if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then 369 | cat "${tmpdir}/docker_build.log" 370 | fi 371 | 372 | log_green "Finished building the docker image." 373 | update_cache="true" 374 | else 375 | log_red "Failed to build the Docker image, aborting." 376 | log_yellow "Dumping the build logs:" 377 | cat "${tmpdir}/docker_build.log" 378 | exit 1 379 | fi 380 | else 381 | if docker build "${docker_build_flags[@]}" "${context_dir}"; then 382 | log_green "Finished building the docker image." 383 | update_cache="true" 384 | else 385 | log_red "Failed to build the Docker image, aborting." 386 | exit 1 387 | fi 388 | fi 389 | else 390 | if [[ "${has_image}" != "true" ]]; then 391 | log_red "We do not have ${TRAMPOLINE_IMAGE} locally, aborting." 392 | exit 1 393 | fi 394 | fi 395 | 396 | # We use an array for the flags so they are easier to document. 397 | docker_flags=( 398 | # Remove the container after it exists. 399 | "--rm" 400 | 401 | # Use the host network. 402 | "--network=host" 403 | 404 | # Run in priviledged mode. We are not using docker for sandboxing or 405 | # isolation, just for packaging our dev tools. 406 | "--privileged" 407 | 408 | # Run the docker script with the user id. Because the docker image gets to 409 | # write in ${PWD} you typically want this to be your user id. 410 | # To allow docker in docker, we need to use docker gid on the host. 411 | "--user" "${user_uid}:${docker_gid}" 412 | 413 | # Pass down the USER. 414 | "--env" "USER=${user_name}" 415 | 416 | # Mount the project directory inside the Docker container. 417 | "--volume" "${PROJECT_ROOT}:${TRAMPOLINE_WORKSPACE}" 418 | "--workdir" "${TRAMPOLINE_WORKSPACE}" 419 | "--env" "PROJECT_ROOT=${TRAMPOLINE_WORKSPACE}" 420 | 421 | # Mount the temporary home directory. 422 | "--volume" "${tmphome}:/h" 423 | "--env" "HOME=/h" 424 | 425 | # Allow docker in docker. 426 | "--volume" "/var/run/docker.sock:/var/run/docker.sock" 427 | 428 | # Mount the /tmp so that docker in docker can mount the files 429 | # there correctly. 430 | "--volume" "/tmp:/tmp" 431 | # Pass down the KOKORO_GFILE_DIR and KOKORO_KEYSTORE_DIR 432 | # TODO(tmatsuo): This part is not portable. 433 | "--env" "TRAMPOLINE_SECRET_DIR=/secrets" 434 | "--volume" "${KOKORO_GFILE_DIR:-/dev/shm}:/secrets/gfile" 435 | "--env" "KOKORO_GFILE_DIR=/secrets/gfile" 436 | "--volume" "${KOKORO_KEYSTORE_DIR:-/dev/shm}:/secrets/keystore" 437 | "--env" "KOKORO_KEYSTORE_DIR=/secrets/keystore" 438 | ) 439 | 440 | # Add an option for nicer output if the build gets a tty. 441 | if [[ -t 0 ]]; then 442 | docker_flags+=("-it") 443 | fi 444 | 445 | # Passing down env vars 446 | for e in "${pass_down_envvars[@]}" 447 | do 448 | if [[ -n "${!e:-}" ]]; then 449 | docker_flags+=("--env" "${e}=${!e}") 450 | fi 451 | done 452 | 453 | # If arguments are given, all arguments will become the commands run 454 | # in the container, otherwise run TRAMPOLINE_BUILD_FILE. 455 | if [[ $# -ge 1 ]]; then 456 | log_yellow "Running the given commands '" "${@:1}" "' in the container." 457 | readonly commands=("${@:1}") 458 | if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then 459 | echo docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" "${commands[@]}" 460 | fi 461 | docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" "${commands[@]}" 462 | else 463 | log_yellow "Running the tests in a Docker container." 464 | docker_flags+=("--entrypoint=${TRAMPOLINE_BUILD_FILE}") 465 | if [[ "${TRAMPOLINE_VERBOSE:-}" == "true" ]]; then 466 | echo docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" 467 | fi 468 | docker run "${docker_flags[@]}" "${TRAMPOLINE_IMAGE}" 469 | fi 470 | 471 | 472 | test_retval=$? 473 | 474 | if [[ ${test_retval} -eq 0 ]]; then 475 | log_green "Build finished with ${test_retval}" 476 | else 477 | log_red "Build finished with ${test_retval}" 478 | fi 479 | 480 | # Only upload it when the test passes. 481 | if [[ "${update_cache}" == "true" ]] && \ 482 | [[ $test_retval == 0 ]] && \ 483 | [[ "${TRAMPOLINE_IMAGE_UPLOAD:-false}" == "true" ]]; then 484 | log_yellow "Uploading the Docker image." 485 | if docker push "${TRAMPOLINE_IMAGE}"; then 486 | log_green "Finished uploading the Docker image." 487 | else 488 | log_red "Failed uploading the Docker image." 489 | fi 490 | # Call trampoline_after_upload_hook if it's defined. 491 | if function_exists trampoline_after_upload_hook; then 492 | trampoline_after_upload_hook 493 | fi 494 | 495 | fi 496 | 497 | exit "${test_retval}" 498 | -------------------------------------------------------------------------------- /.release-please-manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | ".": "1.31.0" 3 | } 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | inherit_from: google-style.yml 2 | -------------------------------------------------------------------------------- /.toys/.toys.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright 2021 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | expand :clean, paths: :gitignore 18 | 19 | expand :rubocop, bundler: true 20 | 21 | expand :gem_build 22 | 23 | tool "release" do 24 | if ENV["RUBY_COMMON_TOOLS"] 25 | common_tools_dir = File.expand_path ENV["RUBY_COMMON_TOOLS"] 26 | load File.join(common_tools_dir, "toys", "release") 27 | else 28 | load_git remote: "https://github.com/googleapis/ruby-common-tools.git", 29 | path: "toys/release", 30 | update: true 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /.trampolinerc: -------------------------------------------------------------------------------- 1 | # Copyright 2021 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | # Add required env vars here. 16 | required_envvars+=( 17 | ) 18 | 19 | # Add env vars which are passed down into the container here. 20 | pass_down_envvars+=( 21 | "AUTORELEASE_PR" 22 | "EXTRA_CI_ARGS" 23 | "KOKORO_GIT_COMMIT" 24 | "RELEASE_DRY_RUN" 25 | "RELEASE_PACKAGE" 26 | "RUBY_VERSIONS" 27 | ) 28 | 29 | # Prevent unintentional override on the default image. 30 | if [[ "${TRAMPOLINE_IMAGE_UPLOAD:-false}" == "true" ]] && [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then 31 | echo "Please set TRAMPOLINE_IMAGE if you want to upload the Docker image." 32 | exit 1 33 | fi 34 | 35 | # Define the default value if it makes sense. 36 | if [[ -z "${TRAMPOLINE_IMAGE_UPLOAD:-}" ]]; then 37 | TRAMPOLINE_IMAGE_UPLOAD="" 38 | fi 39 | 40 | if [[ -z "${TRAMPOLINE_IMAGE:-}" ]]; then 41 | TRAMPOLINE_IMAGE="" 42 | fi 43 | 44 | if [[ -z "${TRAMPOLINE_DOCKERFILE:-}" ]]; then 45 | TRAMPOLINE_DOCKERFILE="" 46 | fi 47 | 48 | if [[ -z "${TRAMPOLINE_BUILD_FILE:-}" ]]; then 49 | TRAMPOLINE_BUILD_FILE="" 50 | fi 51 | 52 | # Secret Manager secrets. 53 | source ${PROJECT_ROOT}/.kokoro/populate-secrets.sh 54 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Release History 2 | 3 | ### 1.31.0 (2025-04-28) 4 | 5 | #### Features 6 | 7 | * update ruby version, audit some cops ([#88](https://github.com/googleapis/ruby-style/issues/88)) 8 | 9 | ### 1.30.1 (2024-10-25) 10 | 11 | #### Bug Fixes 12 | 13 | * Disable SafeNavigationConsistency lint ([#79](https://github.com/googleapis/ruby-style/issues/79)) 14 | 15 | ### 1.30.0 (2024-04-24) 16 | 17 | #### Features 18 | 19 | * Require Ruby 3.0 and support new checks as of Rubocop 1.63 ([#74](https://github.com/googleapis/ruby-style/issues/74)) 20 | 21 | ### 1.27.1 (2024-01-20) 22 | 23 | #### Bug Fixes 24 | 25 | * Disable anonymous argument forwarding requirement ([#71](https://github.com/googleapis/ruby-style/issues/71)) 26 | 27 | ### 1.27.0 (2023-09-13) 28 | 29 | #### Features 30 | 31 | * Require Ruby 2.7 and support new checks as of Rubocop 1.56 ([#64](https://github.com/googleapis/ruby-style/issues/64)) 32 | 33 | ### 1.26.3 (2023-02-09) 34 | 35 | #### Bug Fixes 36 | 37 | * Disable Lint/Debugger for samples ([#60](https://github.com/googleapis/ruby-style/issues/60)) 38 | 39 | ### 1.26.2 (2022-12-08) 40 | 41 | #### Bug Fixes 42 | 43 | * Disable Style/RegexpLiteral ([#58](https://github.com/googleapis/ruby-style/issues/58)) 44 | 45 | ### 1.26.1 (2022-06-27) 46 | 47 | #### Bug Fixes 48 | 49 | * Updates for Rubocop 1.31 ([#54](https://github.com/googleapis/ruby-style/issues/54)) 50 | 51 | ### 1.26.0 (2022-05-27) 52 | 53 | #### Features 54 | 55 | * Require Ruby 2.6 and support new checks as of Rubocop 1.30 56 | 57 | ### 1.25.3 (2022-05-06) 58 | 59 | #### Bug Fixes 60 | 61 | * Pin rubocop to 1.28.x for Ruby 2.5 compatibility 62 | 63 | ### 1.25.2 (2021-09-23) 64 | 65 | * Disable Style/RedundantBegin 66 | 67 | ### 1.25.1 / 2021-02-09 68 | 69 | * Add rubocop 1.9 cops and disable a few others 70 | * Fix crash on extension checking, and eliminate new cop warning 71 | 72 | ### 1.25.0 / 2021-01-27 73 | 74 | * pin rubocop version to 1.x, set min ruby to 2.5, enable new cops 75 | 76 | ### 1.24.0 / 2019-08-08 77 | 78 | * Set required ruby version to 2.4 79 | * Set rubocop dependency to ~> 0.74.0 80 | 81 | ### 0.3.1 / 2019-06-12 82 | 83 | * Fix file permissions 84 | 85 | ### 0.3.0 / 2019-05-06 86 | 87 | * Enforce expanded for Style/EmptyMethod 88 | * Allow parentheses in chaining for Style/MethodCallWithArgsParentheses 89 | * Enforce brackets for Style/WordArray and Style/SymbolArray 90 | 91 | ### 0.2.0 / 2019-03-13 92 | 93 | * Set TargetRubyVersion to 2.3 94 | * Disable Style/FrozenStringLiteralComment 95 | * Enable Metrics/ClassLength 96 | 97 | ### 0.1.0 / 2019-03-07 98 | 99 | * Initial release 100 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Code of Conduct 2 | 3 | As contributors and maintainers of this project, and in the interest of 4 | fostering an open and welcoming community, we pledge to respect all people who 5 | contribute through reporting issues, posting feature requests, updating 6 | documentation, submitting pull requests or patches, and other activities. 7 | 8 | We are committed to making participation in this project a harassment-free 9 | experience for everyone, regardless of level of experience, gender, gender 10 | identity and expression, sexual orientation, disability, personal appearance, 11 | body size, race, ethnicity, age, religion, or nationality. 12 | 13 | Examples of unacceptable behavior by participants include: 14 | 15 | * The use of sexualized language or imagery 16 | * Personal attacks 17 | * Trolling or insulting/derogatory comments 18 | * Public or private harassment 19 | * Publishing other's private information, such as physical or electronic 20 | addresses, without explicit permission 21 | * Other unethical or unprofessional conduct. 22 | 23 | Project maintainers have the right and responsibility to remove, edit, or reject 24 | comments, commits, code, wiki edits, issues, and other contributions that are 25 | not aligned to this Code of Conduct. By adopting this Code of Conduct, project 26 | maintainers commit themselves to fairly and consistently applying these 27 | principles to every aspect of managing this project. Project maintainers who do 28 | not follow or enforce the Code of Conduct may be permanently removed from the 29 | project team. 30 | 31 | This code of conduct applies both within project spaces and in public spaces 32 | when an individual is representing the project or its community. 33 | 34 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 35 | reported by opening an issue or contacting one or more of the project 36 | maintainers. 37 | 38 | This Code of Conduct is adapted from the [Contributor 39 | Covenant](http://contributor-covenant.org), version 1.2.0, available at 40 | [http://contributor-covenant.org/version/1/2/0/](http://contributor-covenant.org/version/1/2/0/) 41 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to Contribute 2 | 3 | We'd love to accept your patches and contributions to this project. There are 4 | just a few small guidelines you need to follow. 5 | 6 | ## Contributor License Agreement 7 | 8 | Contributions to this project must be accompanied by a Contributor License 9 | Agreement. You (or your employer) retain the copyright to your contribution; 10 | this simply gives us permission to use and redistribute your contributions as 11 | part of the project. Head over to to see 12 | your current agreements on file or to sign a new one. 13 | 14 | You generally only need to submit a CLA once, so if you've already submitted one 15 | (even if it was for a different project), you probably don't need to do it 16 | again. 17 | 18 | ## Code reviews 19 | 20 | All submissions, including submissions by project members, require review. We 21 | use GitHub pull requests for this purpose. Consult 22 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more 23 | information on using pull requests. 24 | 25 | ## Community Guidelines 26 | 27 | This project follows [Google's Open Source Community 28 | Guidelines](https://opensource.google.com/conduct/). 29 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | source "https://rubygems.org" 16 | 17 | gemspec 18 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ruby Style Guide 2 | 3 | ## Installation 4 | 5 | Run: 6 | 7 | ```bash 8 | bundle add google-style --group development,test 9 | ``` 10 | 11 | Or, add this line to your Gemfile: 12 | 13 | ```ruby 14 | group :test, :development do 15 | gem "google-style" 16 | end 17 | ``` 18 | 19 | ## Usage 20 | 21 | Add the following to the top of your `.rubocop.yml`: 22 | 23 | ```yaml 24 | inherit_gem: 25 | google-style: google-style.yml 26 | ``` 27 | 28 | And run: 29 | 30 | ```bash 31 | bundle exec rubocop 32 | ``` 33 | 34 | ## Versioning 35 | 36 | For all `1.x.y` gem versions, the target and required Ruby version will match 37 | the minor gem version. Hence, `1.26.y` versions target and require Ruby 2.6. 38 | `1.30.y` versions target and require Ruby 3.0, and so forth. 39 | 40 | During a minor version bump, the rubocop dependency will be updated to the 41 | latest version, and we will enable new checks up to and including that version. 42 | Thus, code that passed using one minor version might not pass using the next. 43 | Hence, dependencies should generally follow the pattern `~> 1.x.y` to pin to a 44 | specific minor version. 45 | 46 | ## Contributing 47 | 48 | Contributions to this library are always welcome and highly encouraged. 49 | 50 | See the [Contributing Guide](CONTRIBUTING.md) 51 | for more information on how to get started. 52 | 53 | Please note that this project is released with a Contributor Code of Conduct. By 54 | participating in this project you agree to abide by its terms. See the [Code of 55 | Conduct](CODE_OF_CONDUCT.md) for more information. 56 | 57 | ## License 58 | 59 | This library is licensed under Apache 2.0. Full license text is available in 60 | [LICENSE](LICENSE). 61 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Security Policy 2 | 3 | To report a security issue, please use [g.co/vulnz](https://g.co/vulnz). 4 | 5 | The Google Security Team will respond within 5 working days of your report on g.co/vulnz. 6 | 7 | We use g.co/vulnz for our intake, and do coordination and disclosure here using GitHub Security Advisory to privately discuss and fix the issue. 8 | -------------------------------------------------------------------------------- /google-style.gemspec: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | lib = File.expand_path "lib", __dir__ 16 | $LOAD_PATH.unshift lib unless $LOAD_PATH.include? lib 17 | require "google/style/version" 18 | 19 | Gem::Specification.new do |gem| 20 | gem.name = "google-style" 21 | gem.version = Google::Style::VERSION 22 | 23 | gem.authors = ["Daniel Azuma", "Graham Paye"] 24 | gem.email = ["dazuma@google.com", "paye@google.com"] 25 | gem.description = "Shared style guide for Google's ruby projects" 26 | gem.summary = "Collection of rubocop rules" 27 | gem.homepage = "https://github.com/googleapis/ruby-style/" 28 | gem.license = "Apache-2.0" 29 | 30 | gem.files = ["CONTRIBUTING.md", "CODE_OF_CONDUCT.md", "LICENSE", 31 | "README.md", "google-style.yml", 32 | "lib/google/style/version.rb"] 33 | 34 | gem.required_ruby_version = ">= 3.1.0" 35 | 36 | gem.add_dependency "rubocop", "~> 1.75" 37 | end 38 | -------------------------------------------------------------------------------- /google-style.yml: -------------------------------------------------------------------------------- 1 | # Copyright 2019 Google LLC 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # https://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | AllCops: 16 | NewCops: disable 17 | SuggestExtensions: false 18 | TargetRubyVersion: 3.1 19 | 20 | Gemspec/AddRuntimeDependency: # new in 1.65 21 | Enabled: true 22 | 23 | # Added in Rubocop 1.30 24 | Gemspec/DeprecatedAttributeAssignment: 25 | Enabled: true 26 | 27 | # Added in Rubocop 1.44 28 | Gemspec/DevelopmentDependencies: 29 | Enabled: true 30 | 31 | # Disabled for now. 32 | Gemspec/RequireMFA: 33 | Enabled: false 34 | 35 | # Enforcing a blank line often worsens vertical layout. 36 | Layout/EmptyLineAfterGuardClause: 37 | Enabled: false 38 | 39 | # For the extra line between copyright and code. 40 | Layout/EmptyLines: 41 | Enabled: false 42 | 43 | # This tends to be problematic, especially for nested hashes. In many cases, 44 | # our code adheres to the "table" style, but we do not want to enforce it. 45 | Layout/HashAlignment: 46 | Enabled: false 47 | 48 | # Added in Rubocop 1.31 49 | Layout/LineContinuationLeadingSpace: 50 | Enabled: true 51 | 52 | # Added in Rubocop 1.31 53 | Layout/LineContinuationSpacing: 54 | Enabled: true 55 | 56 | # Added in Rubocop 1.18 57 | Layout/LineEndStringConcatenationIndentation: 58 | Enabled: true 59 | 60 | # Our current preferred line length. 61 | Layout/LineLength: 62 | Max: 120 63 | 64 | # Added in Rubocop 1.7 65 | Layout/SpaceBeforeBrackets: 66 | Enabled: true 67 | 68 | Lint/ArrayLiteralInRegexp: # new in 1.71 69 | Enabled: true 70 | 71 | # Added in Rubocop 1.7 72 | Lint/AmbiguousAssignment: 73 | Enabled: true 74 | 75 | # Added in Rubocop 1.21 76 | Lint/AmbiguousOperatorPrecedence: 77 | Enabled: true 78 | 79 | # Added in Rubocop 1.19 80 | Lint/AmbiguousRange: 81 | Enabled: true 82 | 83 | # Added in Rubocop 1.31 84 | Lint/ConstantOverwrittenInRescue: 85 | Enabled: true 86 | 87 | Lint/ConstantReassignment: # new in 1.70 88 | Enabled: true 89 | 90 | Lint/CopDirectiveSyntax: # new in 1.72 91 | Enabled: true 92 | 93 | # Samples often use Kernel#p which Lint/Debugger doesn't like. 94 | Lint/Debugger: 95 | Exclude: 96 | - "samples/**/*.rb" 97 | - "snippets/**/*.rb" 98 | 99 | # Added in Rubocop 1.8 100 | Lint/DeprecatedConstants: 101 | Enabled: true 102 | 103 | # Added in Rubocop 1.3 104 | Lint/DuplicateBranch: 105 | Enabled: true 106 | 107 | # Added in Rubocop 1.37 108 | Lint/DuplicateMagicComment: 109 | Enabled: true 110 | 111 | # Added in Rubocop 1.50 112 | Lint/DuplicateMatchPattern: 113 | Enabled: true 114 | 115 | # Added in Rubocop 1.1 116 | Lint/DuplicateRegexpCharacterClassElement: 117 | Enabled: true 118 | 119 | Lint/DuplicateSetElement: # new in 1.67 120 | Enabled: true 121 | 122 | # Added in Rubocop 1.1 123 | Lint/EmptyBlock: 124 | Enabled: true 125 | 126 | # Added in Rubocop 1.3 127 | Lint/EmptyClass: 128 | Enabled: true 129 | 130 | # Added in Rubocop 1.16 131 | Lint/EmptyInPattern: 132 | Enabled: true 133 | 134 | Lint/HashNewWithKeywordArgumentsAsDefault: # new in 1.69 135 | Enabled: true 136 | 137 | # Added in Rubocop 1.21 138 | Lint/IncompatibleIoSelectWithFiberScheduler: 139 | Enabled: true 140 | 141 | # Added in Rubocop 1.59 142 | Lint/ItWithoutArgumentsInBlock: 143 | Enabled: true 144 | 145 | # Added in Rubocop 1.8 146 | Lint/LambdaWithoutLiteralBlock: 147 | Enabled: true 148 | 149 | # Added in Rubocop 1.58 150 | Lint/LiteralAssignmentInCondition: 151 | Enabled: true 152 | 153 | # Added in Rubocop 1.53 154 | Lint/MixedCaseRange: 155 | Enabled: true 156 | 157 | # Added in Rubocop 1.2 158 | Lint/NoReturnInBeginEndBlocks: 159 | Enabled: true 160 | 161 | # Added in Rubocop 1.31 162 | Lint/NonAtomicFileOperation: 163 | Enabled: true 164 | 165 | # Added in Rubocop 1.9 166 | Lint/NumberedParameterAssignment: 167 | Enabled: true 168 | 169 | # Can easily appear in the generated code 170 | Lint/NumericOperationWithConstantResult: # new in 1.69 171 | Enabled: false 172 | 173 | # Added in Rubocop 1.9 174 | Lint/OrAssignmentToConstant: 175 | Enabled: true 176 | 177 | # Added in Rubocop 1.8 178 | Lint/RedundantDirGlobSort: 179 | Enabled: true 180 | 181 | # Added in Rubocop 1.53 182 | Lint/RedundantRegexpQuantifiers: 183 | Enabled: true 184 | 185 | # Can easily appear in the generated code 186 | Lint/RedundantTypeConversion: # new in 1.72 187 | Enabled: false 188 | 189 | # Added in Rubocop 1.27 190 | Lint/RefinementImportMethods: 191 | Enabled: true 192 | 193 | # Added in Rubocop 1.32 194 | Lint/RequireRangeParentheses: 195 | Enabled: true 196 | 197 | # Added in Rubocop 1.22 198 | Lint/RequireRelativeSelfPath: 199 | Enabled: true 200 | 201 | # Could be problematic for code refactoring, and overall not very useful. 202 | Lint/SafeNavigationConsistency: 203 | Enabled: false 204 | 205 | Lint/SharedMutableDefault: # new in 1.70 206 | Enabled: true 207 | 208 | Lint/SuppressedExceptionInNumberConversion: # new in 1.72 209 | Enabled: true 210 | 211 | # Added in Rubocop 1.9 212 | Lint/SymbolConversion: 213 | Enabled: true 214 | 215 | # Added in Rubocop 1.1 216 | Lint/ToEnumArguments: 217 | Enabled: true 218 | 219 | # Added in Rubocop 1.9 220 | Lint/TripleQuotes: 221 | Enabled: true 222 | 223 | # Added in Rubocop 1.5 224 | Lint/UnexpectedBlockArity: 225 | Enabled: true 226 | 227 | Lint/UnescapedBracketInRegexp: # new in 1.68 228 | Enabled: true 229 | 230 | # Added in Rubocop 1.1 231 | Lint/UnmodifiedReduceAccumulator: 232 | Enabled: true 233 | 234 | Lint/UselessConstantScoping: # new in 1.72 235 | Enabled: true 236 | 237 | Lint/UselessDefined: # new in 1.69 238 | Enabled: true 239 | 240 | # Can easily appear in the generated code 241 | Lint/UselessNumericOperation: # new in 1.66 242 | Enabled: false 243 | 244 | # Added in Rubocop 1.43 245 | Lint/UselessRescue: 246 | Enabled: true 247 | 248 | # Added in Rubocop 1.23 249 | Lint/UselessRuby2Keywords: 250 | Enabled: true 251 | 252 | Metrics/AbcSize: 253 | Max: 30 254 | 255 | # Could be problematic for generated code, and overall not very useful. 256 | Metrics/CollectionLiteralLength: 257 | Enabled: false 258 | 259 | Metrics/CyclomaticComplexity: 260 | Max: 10 261 | 262 | Metrics/MethodLength: 263 | Max: 25 264 | 265 | # Sometimes problematic for API calls which might have a lot of parameters, 266 | # and for generated code. 267 | Metrics/ParameterLists: 268 | Enabled: false 269 | 270 | Metrics/PerceivedComplexity: 271 | Max: 10 272 | 273 | # Added in Rubocop 1.24 274 | Naming/BlockForwarding: 275 | Enabled: true 276 | 277 | # Does not allow distinguishing verbs (e.g. is vs has). Also causes problems 278 | # for generated code that might have generated method names. 279 | Naming/PredicateName: 280 | Enabled: false 281 | 282 | # Numbers are occasionally semantically useful in names, and also occasionally 283 | # appear in generated code. 284 | Naming/VariableNumber: 285 | Enabled: false 286 | 287 | # Added in Rubocop 1.28 288 | Security/CompoundHash: 289 | Enabled: true 290 | 291 | # Added in Rubocop 1.22 292 | Security/IoMethods: 293 | Enabled: true 294 | 295 | # Better to separate accessors for yardoc and type declarations. 296 | Style/AccessorGrouping: 297 | EnforcedStyle: separated 298 | 299 | Style/AmbiguousEndlessMethodDefinition: # new in 1.68 300 | Enabled: true 301 | 302 | # Added in Rubocop 1.1 303 | Style/ArgumentsForwarding: 304 | Enabled: true 305 | RedundantBlockArgumentNames: [] # To support Ruby < 3.2 306 | RedundantKeywordRestArgumentNames: [] # To support Ruby < 3.2 307 | RedundantRestArgumentNames: [] # To support Ruby < 3.2 308 | UseAnonymousForwarding: false # To support Ruby < 3.2 309 | 310 | Style/ArrayIntersect: # new in 1.40 311 | Enabled: true 312 | 313 | # Problematic for generated code which might include unicode in comments. 314 | Style/AsciiComments: 315 | Enabled: false 316 | 317 | # There are cases where we use the === operator as a general interface, e.g. 318 | # when specifying type checker objects. 319 | Style/CaseEquality: 320 | Enabled: false 321 | 322 | # Added in Rubocop 1.2 323 | Style/CollectionCompact: 324 | Enabled: true 325 | 326 | Style/CombinableDefined: # new in 1.68 327 | Enabled: true 328 | 329 | # Added in Rubocop 1.44 330 | Style/ComparableClamp: 331 | Enabled: true 332 | 333 | # Added in Rubocop 1.41 334 | Style/ConcatArrayLiterals: 335 | Enabled: true 336 | 337 | Style/DigChain: # new in 1.69 338 | Enabled: true 339 | 340 | # Added in Rubocop 1.48 341 | Style/DirEmpty: 342 | Enabled: true 343 | 344 | # Added in Rubocop 1.1 345 | Style/DocumentDynamicEvalDefinition: 346 | Enabled: true 347 | 348 | # Added in Rubocop 1.32 349 | Style/EmptyHeredoc: 350 | Enabled: true 351 | 352 | # We prefer consistent method indentation. 353 | Style/EmptyMethod: 354 | EnforcedStyle: expanded 355 | 356 | # Added in Rubocop 1.8 357 | Style/EndlessMethod: 358 | Enabled: true 359 | 360 | # Added in Rubocop 1.29 361 | Style/EnvHome: 362 | Enabled: true 363 | 364 | # Added in Rubocop 1.51 365 | Style/ExactRegexpMatch: 366 | Enabled: true 367 | 368 | # This check is overly paranoid. 369 | Style/FetchEnvVar: 370 | Enabled: false 371 | 372 | # Added in Rubocop 1.48 373 | Style/FileEmpty: 374 | Enabled: true 375 | 376 | # Added in Rubocop 1.24 377 | Style/FileRead: 378 | Enabled: true 379 | 380 | # Added in Rubocop 1.24 381 | Style/FileWrite: 382 | Enabled: true 383 | 384 | # Frozen string literals are no more as of Ruby 3. 385 | Style/FrozenStringLiteralComment: 386 | Enabled: false 387 | 388 | # Added in Rubocop 1.10 389 | Style/HashConversion: 390 | Enabled: true 391 | 392 | # Added in Rubocop 1.7 393 | Style/HashExcept: 394 | Enabled: true 395 | 396 | Style/HashFetchChain: # new in 1.75 397 | Enabled: true 398 | 399 | # It is sometimes preferable to use the non-modifier form even for single-line 400 | # expressions, for readability. 401 | Style/IfUnlessModifier: 402 | Enabled: false 403 | 404 | # Added in Rubocop 1.9 405 | Style/IfWithBooleanLiteralBranches: 406 | Enabled: true 407 | 408 | # Added in Rubocop 1.16 409 | Style/InPatternThen: 410 | Enabled: true 411 | 412 | Style/ItAssignment: # new in 1.70 413 | Enabled: true 414 | 415 | Style/ItBlockParameter: # new in 1.75 416 | Enabled: true 417 | 418 | # Added in Rubocop 1.35 419 | Style/MagicCommentFormat: 420 | Enabled: true 421 | 422 | # Added in Rubocop 1.30 423 | Style/MapCompactWithConditionalBlock: 424 | Enabled: true 425 | 426 | # Added in Rubocop 1.63 427 | Style/MapIntoArray: 428 | Enabled: true 429 | 430 | # Added in Rubocop 1.24 431 | Style/MapToHash: 432 | Enabled: true 433 | 434 | # Added in Rubocop 1.42 435 | Style/MapToSet: 436 | Enabled: true 437 | 438 | # We adopt Seattle-style paren usage 439 | Style/MethodCallWithArgsParentheses: 440 | AllowParenthesesInCamelCaseMethod: true 441 | AllowParenthesesInChaining: true 442 | AllowParenthesesInMultilineCall: true 443 | Enabled: true 444 | EnforcedStyle: omit_parentheses 445 | 446 | # We adopt Seattle-style paren usage 447 | Style/MethodDefParentheses: 448 | EnforcedStyle: require_no_parentheses 449 | 450 | # I (dazuma@) am not a fan of this rule. It's a bit more readable but at the 451 | # cost of being logically clever. 452 | Style/MinMaxComparison: 453 | Enabled: false 454 | 455 | # Enable use of the different semantics of module_function and extend self. 456 | Style/ModuleFunction: 457 | Enabled: false 458 | 459 | # Added in Rubocop 1.16 460 | Style/MultilineInPatternThen: 461 | Enabled: true 462 | 463 | # I (dazuma@) am not a fan of this rule. Its readability benefit is debatable 464 | # and it carries the cost of being logically clever. 465 | Style/MultipleComparison: 466 | Enabled: false 467 | 468 | # Added in Rubocop 1.2 469 | Style/NegatedIfElseCondition: 470 | Enabled: true 471 | 472 | # Added in Rubocop 1.26 473 | Style/NestedFileDirname: 474 | Enabled: true 475 | 476 | # Added in Rubocop 1.3 477 | Style/NilLambda: 478 | Enabled: true 479 | 480 | # Added in Rubocop 1.22 481 | Style/NumberedParameters: 482 | Enabled: true 483 | 484 | # Added in Rubocop 1.22 485 | Style/NumberedParametersLimit: 486 | Enabled: true 487 | 488 | # Added in Rubocop 1.28 489 | Style/ObjectThen: 490 | Enabled: true 491 | 492 | # Disabled for tests but left enabled for production code. 493 | # Added in Rubocop 1.23 494 | Style/OpenStructUse: 495 | Enabled: true 496 | Exclude: 497 | - "test/**/*.rb" 498 | - "acceptance/**/*.rb" 499 | - "samples/acceptance/**/*.rb" 500 | 501 | # Added in Rubocop 1.37. Open to disabling this if it causes problems for 502 | # metaprogramming-heavy code. 503 | Style/OperatorMethodCall: 504 | Enabled: true 505 | 506 | # Added in Rubocop 1.16 507 | Style/QuotedSymbols: 508 | Enabled: true 509 | 510 | # Added in Rubocop 1.4 511 | Style/RedundantArgument: 512 | Enabled: true 513 | 514 | # Added in Rubocop 1.52 515 | Style/RedundantArrayConstructor: 516 | Enabled: true 517 | 518 | # Disabled because we prefer to keep begin-end blocks in memoization for 519 | # readability (see https://github.com/rubocop/rubocop/pull/9602). 520 | Style/RedundantBegin: 521 | Enabled: false 522 | 523 | # Disabled because we believe it's good practice to be explicit about constant 524 | # namespaces, given how confusing constant lookup rules are in Ruby. 525 | Style/RedundantConstantBase: 526 | Enabled: false 527 | 528 | # Added in Rubocop 1.53 529 | Style/RedundantCurrentDirectoryInPath: 530 | Enabled: true 531 | 532 | # Added in Rubocop 1.41 533 | Style/RedundantDoubleSplatHashBraces: 534 | Enabled: true 535 | 536 | # Added in Rubocop 1.38 537 | Style/RedundantEach: 538 | Enabled: true 539 | 540 | # Added in Rubocop 1.52 541 | Style/RedundantFilterChain: 542 | Enabled: true 543 | 544 | # Added in Rubocop 1.45 545 | Style/RedundantHeredocDelimiterQuotes: 546 | Enabled: true 547 | 548 | # Added in Rubocop 1.27 549 | Style/RedundantInitialize: 550 | Enabled: true 551 | 552 | # Added in Rubocop 1.49 553 | Style/RedundantLineContinuation: 554 | Enabled: true 555 | 556 | # Added in Rubocop 1.53 557 | Style/RedundantRegexpArgument: 558 | Enabled: true 559 | 560 | # Added in Rubocop 1.52 561 | Style/RedundantRegexpConstructor: 562 | Enabled: true 563 | 564 | # Added in Rubocop 1.19 565 | Style/RedundantSelfAssignmentBranch: 566 | Enabled: true 567 | 568 | # Added in Rubocop 1.37 569 | Style/RedundantStringEscape: 570 | Enabled: true 571 | 572 | # Disabled because we find it to be pedantic. The enforced rules are too simple 573 | # to capture readability, and are especially problematic for generated code. 574 | Style/RegexpLiteral: 575 | Enabled: false 576 | 577 | # The idiom is useful in a variety of cases. We prefer to allow it. 578 | Style/RescueModifier: 579 | Enabled: false 580 | 581 | # Added in Rubocop 1.53. Open to disabling, since there may be exceptions. 582 | Style/ReturnNilInPredicateMethodDefinition: 583 | Enabled: true 584 | 585 | # Disabled since length of navigation chain is not a problem. 586 | Style/SafeNavigationChainLength: # new in 1.68 587 | Enabled: false 588 | 589 | # We disagree with this one. Grep is more specialized than select/reject. 590 | Style/SelectByRegexp: 591 | Enabled: false 592 | 593 | # Added in Rubocop 1.57 594 | Style/SingleLineDoEndBlock: 595 | Enabled: true 596 | 597 | # Added in Rubocop 1.12 598 | Style/StringChars: 599 | Enabled: true 600 | 601 | # We prefer standardizing on double-quoted strings for readability. 602 | Style/StringLiterals: 603 | EnforcedStyle: double_quotes 604 | 605 | # We prefer omitting parentheses where possible. 606 | Style/SuperWithArgsParentheses: 607 | Enabled: false 608 | 609 | # Added in Rubocop 1.1 610 | Style/SwapValues: 611 | Enabled: true 612 | 613 | # We prefer traditional bracket style for all arrays. 614 | Style/SymbolArray: 615 | EnforcedStyle: brackets 616 | 617 | # There are some cases where a full method shows intent better than an attr. 618 | Style/TrivialAccessors: 619 | Enabled: false 620 | 621 | # We prefer traditional bracket style for all arrays. 622 | Style/WordArray: 623 | EnforcedStyle: brackets 624 | 625 | # Added in Rubocop 1.53 626 | Style/YAMLFileRead: 627 | Enabled: true 628 | -------------------------------------------------------------------------------- /lib/google/style/version.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | # Copyright 2021 Google LLC 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # https://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | module Google 18 | module Style 19 | VERSION = "1.31.0" 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /release-please-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "bump-minor-pre-major": true, 3 | "bump-patch-for-minor-pre-major": false, 4 | "draft": false, 5 | "include-component-in-tag": true, 6 | "include-v-in-tag": true, 7 | "prerelease": false, 8 | "release-type": "ruby-yoshi", 9 | "skip-github-release": false, 10 | "separate-pull-requests": true, 11 | "tag-separator": "/", 12 | "sequential-calls": true, 13 | "packages": { 14 | ".": { 15 | "component": "google-style", 16 | "version-file": "lib/google/style/version.rb" 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "config:base" 4 | ] 5 | } 6 | --------------------------------------------------------------------------------