|
14 | 14 | # See the License for the specific language governing permissions and |
15 | 15 | # limitations under the License. |
16 | 16 |
|
17 | | -################################################################################ |
18 | | -# Produces wheels that can be uploaded to the pypi package repository. |
19 | | -# |
20 | | -# First argument must be the output directory. Second argument is an optional |
21 | | -# version specifier. If not set, the version from `_version.py` is used. If set, |
22 | | -# it overwrites `_version.py`. |
23 | | -# |
24 | | -# Usage: |
25 | | -# dev_tools/packaging/produce-package.sh output_dir [version] |
26 | | -################################################################################ |
| 17 | +set -o errexit |
| 18 | +set -o nounset |
27 | 19 |
|
28 | | -set -e |
29 | 20 | trap "{ echo -e '\033[31mFAILED\033[0m'; }" ERR |
30 | 21 |
|
31 | | -if [ -z "${1}" ]; then |
32 | | - echo -e "\033[31mNo output directory given.\033[0m" |
33 | | - exit 1 |
34 | | -fi |
35 | | -out_dir=$(realpath "${1}") |
| 22 | +DOC="\ |
| 23 | +usage: $0 [options] output_dir [version] |
| 24 | +
|
| 25 | +Produces wheels that can be uploaded to the pypi package repository. |
| 26 | +
|
| 27 | +First argument must be the output directory. Second argument is an optional |
| 28 | +version specifier, which overwrites the version in _version.py files. |
| 29 | +If not set, the version from _version.py is used as is. |
36 | 30 |
|
37 | | -SPECIFIED_VERSION="${2}" |
| 31 | +Options: |
| 32 | +
|
| 33 | + -c, --commit=COMMIT create wheels from sources at COMMIT instead of HEAD |
| 34 | + -h, --help display this message and exit. |
| 35 | +" |
| 36 | + |
| 37 | +out_dir="" |
| 38 | +specified_version="" |
| 39 | +commitish=HEAD |
| 40 | + |
| 41 | + |
| 42 | +die() { |
| 43 | + ( shift; echo -e "\033[31m${*}\033[0m" ) |
| 44 | + exit "$1" |
| 45 | +} |
38 | 46 |
|
39 | 47 | # Helper to isolate dev_tools/modules.py from Python environment variables |
40 | 48 | my_dev_tools_modules() { |
41 | 49 | python3 -E dev_tools/modules.py "$@" |
42 | 50 | } |
43 | 51 |
|
44 | | -# Get the working directory to the repo root. |
| 52 | +# Process command-line arguments |
| 53 | +while (( $# )); do |
| 54 | + case "$1" in |
| 55 | + -h|--help) |
| 56 | + echo "$DOC" |
| 57 | + exit 0 |
| 58 | + ;; |
| 59 | + -c?*) |
| 60 | + commitish="${1#-c}" |
| 61 | + ;; |
| 62 | + --commit=?*) |
| 63 | + commitish="${1#*=}" |
| 64 | + ;; |
| 65 | + -c|--commit) |
| 66 | + shift |
| 67 | + (( $# )) || die 2 "Option '-c,--commit' requires an argument." |
| 68 | + commit="$1" |
| 69 | + ;; |
| 70 | + *) |
| 71 | + if [[ -z "${out_dir}" ]]; then |
| 72 | + out_dir=$(realpath "${1}") |
| 73 | + elif [[ -z "${specified_version}" ]]; then |
| 74 | + specified_version="${1}" |
| 75 | + else |
| 76 | + die 2 "Unrecognized argument '$1'." |
| 77 | + fi |
| 78 | + ;; |
| 79 | + esac |
| 80 | + shift |
| 81 | +done |
| 82 | + |
| 83 | +if [[ -z "${out_dir}" ]]; then |
| 84 | + die 2 "No output directory given." |
| 85 | +fi |
| 86 | + |
| 87 | +# Change to the root of the Cirq git repository |
45 | 88 | thisdir=$(dirname "${BASH_SOURCE[0]:?}") |
46 | 89 | repo_dir=$(git -C "${thisdir}" rev-parse --show-toplevel) |
47 | 90 | cd "${repo_dir}" |
48 | 91 |
|
49 | | -# Make a clean copy of HEAD, without files ignored by git (but potentially kept by setup.py). |
50 | | -if [ -n "$(git status --short)" ]; then |
| 92 | +# Validate and resolve the commit value |
| 93 | +commit=$(git rev-parse --verify --quiet "${commitish}^{commit}") || |
| 94 | + die "$?" "Invalid commit identifier '${commitish}'" |
| 95 | + |
| 96 | +# Make a pristine temporary clone of the Cirq repository |
| 97 | +if [[ -n "$(git status --short)" ]]; then |
51 | 98 | echo -e "\033[31mWARNING: You have uncommitted changes. They won't be included in the package.\033[0m" |
52 | 99 | fi |
| 100 | + |
53 | 101 | tmp_git_dir=$(mktemp -d "/tmp/produce-package-git.XXXXXXXXXXXXXXXX") |
54 | | -trap '{ rm -rf "${tmp_git_dir}"; }' EXIT |
55 | 102 | echo "Creating pristine repository clone at ${tmp_git_dir}" |
56 | | -git clone --shared --quiet "${repo_dir}" "${tmp_git_dir}" |
| 103 | +git clone --shared --quiet --no-checkout "${repo_dir}" "${tmp_git_dir}" |
57 | 104 | cd "${tmp_git_dir}" |
58 | | -if [ -n "${SPECIFIED_VERSION}" ]; then |
59 | | - CURRENT_VERSION=$(my_dev_tools_modules print_version) |
60 | | - my_dev_tools_modules replace_version --old="${CURRENT_VERSION}" --new="${SPECIFIED_VERSION}" |
| 105 | +git checkout --quiet "${commit}" |
| 106 | + |
| 107 | +if [[ -n "${specified_version}" ]]; then |
| 108 | + current_version=$(my_dev_tools_modules print_version) |
| 109 | + my_dev_tools_modules replace_version --old="${current_version}" --new="${specified_version}" |
61 | 110 | fi |
62 | 111 |
|
63 | 112 | # Python 3 wheel. |
64 | | -echo "Producing python 3 package files." |
| 113 | +echo "Producing Python 3 package files." |
65 | 114 |
|
66 | | -CIRQ_MODULES=$(my_dev_tools_modules list --mode folder --include-parent) |
67 | | -date_epoch=$(git log -1 --pretty="%ct") |
| 115 | +# Reuse SOURCE_DATE_EPOCH if specified in the caller environment |
| 116 | +date_epoch=${SOURCE_DATE_EPOCH:-$(git log -1 --pretty="%ct")} |
| 117 | +cirq_modules=$(my_dev_tools_modules list --mode folder --include-parent) |
68 | 118 |
|
69 | | -for m in $CIRQ_MODULES; do |
70 | | - echo "creating wheel for ${m}" |
71 | | - SOURCE_DATE_EPOCH="${date_epoch}" \ |
72 | | - python3 -m pip wheel --no-deps --wheel-dir="${out_dir}" "./${m}" |
| 119 | +for m in ${cirq_modules}; do |
| 120 | + echo "creating wheel for ${m}" |
| 121 | + SOURCE_DATE_EPOCH="${date_epoch}" \ |
| 122 | + python3 -m pip wheel --no-deps --wheel-dir="${out_dir}" "./${m}" |
73 | 123 | done |
74 | 124 |
|
75 | 125 | ls "${out_dir}" |
| 126 | + |
| 127 | +# Final clean up (all is well if we got here) |
| 128 | +cd "${repo_dir}" |
| 129 | +rm -rf "${tmp_git_dir}" |
0 commit comments