• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/bin/bash -e
2#
3# Copyright 2020 The ChromiumOS Authors
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6#
7# Runs protoc over the configuration protos to produce generated proto code.
8
9# Allows the recursive glob for proto files below to work.
10shopt -s globstar
11
12sha256_even_empty() {
13  sha256sum <( [ -e "${1}" ] || echo )
14}
15
16script_dir="$(dirname "$(realpath -e "${BASH_SOURCE[0]}")")"
17readonly script_dir
18cd "${script_dir}"
19
20readonly desc_file="generated/descriptors.json"
21readonly gen_owners="generated/OWNERS"
22
23desc_file_sha=$(sha256_even_empty "${desc_file}")
24readonly desc_file_sha
25
26gen_owners_sha=$(sha256_even_empty "${gen_owners}")
27readonly gen_owners_sha
28
29regenerate_golden() {
30    # We want to split --path from the filenames so silence warning.
31    # shellcheck disable=2068
32    buf build --exclude-imports -o -#format=json ${proto_paths[@]} \
33        | jq -S > "${desc_file}"
34}
35
36allow_breaking=0
37regen_golden=0
38while [[ $# -gt 0 ]]; do
39    case $1 in
40        --allow-breaking)
41            allow_breaking=1
42            shift
43            ;;
44        --force-regen-golden)
45            regen_golden=1
46            shift
47            ;;
48        *)
49            break
50            ;;
51    esac
52done
53
54./generate_grpc_py_bindings.sh
55
56source "setup_cipd.sh"
57
58if [[ "${regen_golden}" -eq 1 ]]; then
59  echo "Forcing regenerating of golden proto descriptors."
60  regenerate_golden
61  exit 0
62fi
63
64echo "protoc version: $(protoc --version)"
65echo "buf version:    $(buf --version 2>&1)"
66
67#### protobuffer checks
68mapfile -t proto_files < <(find proto/ -type f -name '*.proto')
69mapfile -t proto_paths < \
70        <(find proto/ -type f -name '*.proto' -exec echo '--path {} ' \;)
71
72echo
73echo "== Checking for breaking protobuffer changes"
74if ! buf breaking --against "${desc_file}"; then
75    if [[ "${allow_breaking}" -eq 0 ]]; then
76      (
77          echo
78          cat <<-EOF
79One or more breaking changes detected.  If these are intentional, re-run
80with --allow-breaking to allow the changes.
81EOF
82      ) >&2
83      exit 1
84    else
85      cat <<EOF >&2
86One or more breaking changes, but --allow-breaking specified, continuing.
87EOF
88    fi
89fi
90
91echo "No breaking changes, regenerating '${desc_file}'"
92# We want to split --path from the filenames so suppress warning about quotes.
93# shellcheck disable=2068
94buf build --exclude-imports --exclude-source-info \
95    -o -#format=json ${proto_paths[@]}            \
96    | jq -S > "${desc_file}"
97
98# Check if golden file changed and inform use to commit it.
99if [[ "$(sha256_even_empty "${desc_file}")" != "${desc_file_sha}" ]]; then
100  echo
101  echo "Please commit ${desc_file} with your change"
102else
103  echo "Clean diff on ${desc_file}, nothing else to do." >&2
104fi
105
106echo
107echo "== Linting protobuffers"
108
109# We want to split --path from the filenames so suppress warning about quotes.
110# shellcheck disable=2068
111if ! buf lint ${proto_paths[@]}; then
112  echo "One or more files need cleanup" >&2
113  exit
114else
115  echo "Files are clean"
116fi
117
118echo
119echo "== Generating Python bindings"
120
121# Remove files from prior python protocol buffer code generation in
122# case any .proto files have been removed.
123find python/ -type f -name '*_pb2.py' -delete
124find python/chromiumos -mindepth 1 -type d -not -name __pycache__ \
125  -exec rm -f '{}/__init__.py' \;
126
127protoc -Iproto \
128  --python_out=python "${proto_files[@]}"
129find python/chromiumos -mindepth 1 -type d -not -name __pycache__ \
130  -exec touch '{}/__init__.py' \;
131
132echo
133echo "== Generating Go bindings"
134
135# Go bindings are already namespaced under go.chromium.org/chromiumos/config/go
136# We remove the "chromiumos/config" prefix from local path to avoid redundant
137# namespaceing.
138
139# Remove files from prior go protocol buffer code generation in
140# case any .proto files have been removed.
141find go/ -name '*pb.go' -delete
142
143GO_TEMP_DIR=$(mktemp -d)
144readonly GO_TEMP_DIR
145trap 'rm -rf ${GO_TEMP_DIR}' EXIT
146
147protoc -Iproto \
148  --go_out="${GO_TEMP_DIR}" --go_opt=paths=source_relative \
149  "${proto_files[@]}" \
150  --go-grpc_out="${GO_TEMP_DIR}" \
151  --go-grpc_opt=require_unimplemented_servers=false,paths=source_relative \
152  "${proto_files[@]}";
153
154echo
155echo "== Generating OWNERS file for generated code paths"
156{
157    echo "##### AUTO-GENERATED FILE #####"
158    echo "##### See generate.sh     #####"
159} > "${gen_owners}"
160
161find proto/* -type f -name "OWNERS*" -exec cat {} + | grep -E '^include' | sort | uniq >> "${gen_owners}"
162find proto/* -type f -name "OWNERS*" -exec cat {} + | grep -E '^[a-z0-9]+@.+\..+' | sort | uniq >> "${gen_owners}"
163
164
165if [[ $(sha256_even_empty "${gen_owners}") != "${gen_owners_sha}" ]]; then
166  echo
167  echo "An OWNERS file was updated in the src/config/proto directory."
168  echo "${gen_owners} was automatically updated based on this change."
169  echo "Please commit ${gen_owners} with your change."
170fi
171
172GO_OUT_DIR="go/src/go.chromium.org/chromiumos/config/go"
173
174cp -rf "${GO_TEMP_DIR}"/chromiumos/config/* "${GO_OUT_DIR}"/
175cp "${GO_TEMP_DIR}"/chromiumos/*.go "${GO_OUT_DIR}"/
176cp "${GO_TEMP_DIR}"/chromiumos/longrunning/*.go "${GO_OUT_DIR}"/longrunning/
177cp -rf "${GO_TEMP_DIR}"/chromiumos/build/* "${GO_OUT_DIR}"/build/
178cp -rf "${GO_TEMP_DIR}"/chromiumos/test/* "${GO_OUT_DIR}"/test/
179
180echo
181echo "== Regenerating DutAttributes"
182starlark/dut_attributes/generate
183