blob: 3769db1c2cc0b59ef7e8beae252a0ceb68cd48f9 [file] [log] [blame]
#!/bin/bash
# Copyright 2025 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
# The main Cargo.toml is at third_party/rust_crates/Cargo.toml. This script is at
# third_party/rust_crates/forks/bluetooth/update_bluetooth.sh.
main_cargo_toml_path=$(realpath "$(dirname "${BASH_SOURCE[0]}")"/../../Cargo.toml)
if [ ! -f "$main_cargo_toml_path" ]; then
echo "Error: Could not find main Cargo.toml at $main_cargo_toml_path"
exit 1
fi
# Extract all dependency sections from the main Cargo.toml.
# This looks for any line that ends with .dependencies]
deps_sections=$(awk '/^\[.*dependencies\]/{p=1;next} /^\[/{p=0} p' "$main_cargo_toml_path")
declare -A external_crate_versions
declare -A fuchsia_versions
while IFS= read -r line; do
# Trim leading whitespace and skip empty lines or comments
line=$(echo "$line" | sed -e 's/^[ \t]*//' -e 's/[ \t]*#.*$//')
if [[ -z "$line" || "$line" =~ ^bt- ]]; then
continue
fi
crate_name=$(echo "$line" | cut -d'=' -f1 | tr -d ' "')
external_crate_versions[$crate_name]="$line"
# Extract the version number, handling formats like `version = "1.2.3"` and `= "1.2.3"` or `"1.2.3"`
version=$(echo "$line" | sed -n 's/.*version\s*=\s*"\([^"]*\)".*/\1/p')
if [ -z "$version" ]; then
version=$(echo "$line" | sed -n 's/.*=\s*["=]*\([0-9.]\+\).*/\1/p')
fi
fuchsia_versions[$crate_name]="$version"
done <<< "$deps_sections"
export TMP_CHECKOUT=$(mktemp -d)
if [[ $# -ne 1 || $1 == "--help" ]]; then
echo "Usage: ./update_bluetooth.sh [git_ref]";
exit -1
fi
git_ref=$1;
git clone -n --depth=1 --filter=tree:0 https://bluetooth.googlesource.com/bluetooth $TMP_CHECKOUT
bluetooth_mirror_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null 2>&1 && pwd);
echo "Checking out $git_ref into $bluetooth_mirror_dir...";
cd $TMP_CHECKOUT;
git fetch https://bluetooth.googlesource.com/bluetooth $git_ref
git sparse-checkout set --no-cone /rust LICENSE
git checkout --quiet FETCH_HEAD -- .
declare -A bluetooth_versions
declare -A mismatched_crates
bluetooth_workspace_cargo_toml="$TMP_CHECKOUT/rust/Cargo.toml"
if [ -f "$bluetooth_workspace_cargo_toml" ]; then
bluetooth_deps_section=$(awk '/^\[workspace\.dependencies\]/{p=1;next} /^\[/{p=0} p' "$bluetooth_workspace_cargo_toml")
while IFS= read -r line; do
line=$(echo "$line" | sed -e 's/^[ \t]*//' -e 's/[ \t]*#.*$//')
if [[ -z "$line" ]]; then
continue
fi
crate_name=$(echo "$line" | cut -d'=' -f1 | tr -d ' "')
# Extract the version number, handling formats like `version = "1.2.3"` and `= "1.2.3"` or `"1.2.3"`
version=$(echo "$line" | sed -n 's/.*version\s*=\s*"\([^"]*\)".*/\1/p')
if [ -z "$version" ]; then
version=$(echo "$line" | sed -n 's/.*=\s*["=]*\([0-9.]\+\).*/\1/p')
fi
bluetooth_versions[$crate_name]="$version"
done <<< "$bluetooth_deps_section"
for crate_name in "${!fuchsia_versions[@]}"; do
fuchsia_version=${fuchsia_versions[$crate_name]}
bluetooth_version=${bluetooth_versions[$crate_name]}
if [[ -n "$bluetooth_version" && "$fuchsia_version" != "$bluetooth_version" ]]; then
mismatched_crates[$crate_name]=1
fi
done
else
echo "Warning: Could not find bluetooth workspace Cargo.toml at $bluetooth_workspace_cargo_toml. Skipping version check."
fi
licenses_to_solidify=$(find rust -name LICENSE);
for target in $licenses_to_solidify
do
cp --remove-destination LICENSE $target
done
files_to_persist=(README.fuchsia update_bluetooth.sh)
for persist in ${files_to_persist[@]}
do
cp -v $bluetooth_mirror_dir/$persist $TMP_CHECKOUT/rust/
done
#
# Update the Cargo.toml in the crates to remove all of *.workspace = true
# since rules_rust can't find the workspace file.
# See https://github.com/bazelbuild/rules_rust/issues/3059
crate_paths=rust/bt-*
for crate in ${crate_paths[@]}
do
sed -i -e 's/edition.workspace = true/edition = "2021"/' $crate/Cargo.toml
sed -i -e 's/license.workspace = true/license = "BSD-2-Clause"/' $crate/Cargo.toml
# Handle internal crates (including dev-dependencies) by replacing workspace = true
# with a relative path.
for internal_crate_name in $crate_paths
do
crate_name=${internal_crate_name#"rust/"}
# For dependencies like: `bt-foo.workspace = true`
sed -i -e "s/$crate_name.workspace = true/$crate_name = { path = \"..\\/$crate_name\" }/" $crate/Cargo.toml
# For dependencies like: `bt-foo = { workspace = true, ... }`
sed -i -e "s/$crate_name = { workspace = true, /$crate_name = { path = \"..\\/$crate_name\", /" $crate/Cargo.toml
done
# Handle external crates by replacing workspace = true with the full version string.
for external_crate_name in "${!external_crate_versions[@]}"
do
full_def=${external_crate_versions[$external_crate_name]}
# Use | as a separator to avoid issues with special characters in the replacement string.
sed -i -e "s|$external_crate_name.workspace = true|$full_def|" "$crate/Cargo.toml"
done
done
rm -r $bluetooth_mirror_dir
mkdir $bluetooth_mirror_dir
cp -rv rust/* $bluetooth_mirror_dir/
if [ ${#mismatched_crates[@]} -ne 0 ]; then
echo ""
echo -e "\033[0;33m" # Yellow color for warning
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo "WARNING: Bluetooth crate dependency versions are out of sync with Fuchsia."
echo -e "\033[90mPlease update the versions in the bluetooth repository's rust/Cargo.toml to match.\033[0m"
echo ""
echo "The following crates have mismatched versions:"
for crate_name in "${!mismatched_crates[@]}"; do
echo " - $crate_name (Fuchsia: ${fuchsia_versions[$crate_name]}, Bluetooth: ${bluetooth_versions[$crate_name]})"
done
echo ""
echo "Update rust/Cargo.toml in the bluetooth repository with these lines:"
for crate_name in "${!mismatched_crates[@]}"; do
echo " ${external_crate_versions[$crate_name]}"
done
echo "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
echo -e "\033[0m" # Reset color
fi
echo ""
echo -e "\033[0;32mRun \`fx update-rustc-third-party\` to complete crate update. If it fails, try commenting out the targets that use the bluetooth crates and rerun the command again.\033[0m"
echo ""
echo "Done"