diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index d07ef88044d..6a4d284cd5c 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -59,6 +59,7 @@ /libraries/ESP_SR/ @me-no-dev /libraries/ESPmDNS/ @me-no-dev /libraries/Ethernet/ @me-no-dev +/libraries/Hash/ @lucasssvaz /libraries/Matter/ @SuGlider /libraries/NetBIOS/ @me-no-dev /libraries/Network/ @me-no-dev diff --git a/.github/scripts/get_affected.py b/.github/scripts/get_affected.py index 85e35c40e43..a85f30470e2 100755 --- a/.github/scripts/get_affected.py +++ b/.github/scripts/get_affected.py @@ -358,6 +358,59 @@ def build_qname_from_tag(tag: dict) -> str: qname = "::".join([p for p in qparts if p]) return f"{qname}{signature}" +def find_impl_files_for_qname(qname: str, defs_by_qname: dict[str, set[str]], header_path: str = None) -> set[str]: + """ + Find implementation files for a qualified name, handling namespace mismatches. + + Ctags may capture different namespace scopes in headers vs implementations. + For example: + - Header: fs::SDFS::begin(...) + - Implementation: SDFS::begin(...) + + This happens when implementations use "using namespace" directives. + + Strategy: + 1. Try exact match first + 2. If no match and qname has namespaces, try stripping ONLY outer namespace prefixes + (keep at least Class::method structure intact) + 3. If header_path provided, prefer implementations from same directory + """ + # Try exact match first + impl_files = defs_by_qname.get(qname, set()) + if impl_files: + return impl_files + + # If no exact match and the qname contains namespaces (::), try stripping them + if "::" in qname: + parts = qname.split("::") + # Only strip outer namespaces, not the class/method structure + # For "ns1::ns2::Class::method(...)", we want to try: + # - "ns2::Class::method(...)" (strip 1 level) + # - "Class::method(...)" (strip 2 levels) + # But NOT "method(...)" alone (too ambiguous) + + # Only allow stripping if we have more than 2 parts (namespace::Class::method) + # If we only have 2 parts (Class::method), don't strip as it would leave just "method" + if len(parts) > 2: + # Keep at least 2 parts (Class::method) to avoid false positives + max_strip = len(parts) - 2 + + for i in range(1, max_strip + 1): + shorter_qname = "::".join(parts[i:]) + impl_files = defs_by_qname.get(shorter_qname, set()) + + if impl_files: + # If we have the header path, prefer implementations from same directory + if header_path: + header_dir = os.path.dirname(header_path) + same_dir_files = {f for f in impl_files if os.path.dirname(f) == header_dir} + if same_dir_files: + return same_dir_files + + return impl_files + + return set() + def run_ctags_and_index(paths: list[str]) -> tuple[dict[str, set[str]], dict[str, set[str]], str]: """ Run Universal Ctags over given paths (relative to project_root) and build: @@ -582,8 +635,10 @@ def build_dependencies_graph() -> None: if qnames: impl_files = set() for qn in qnames: - # For each qualified name, get the implementation files - impl_files |= ctags_defs_by_qname.get(qn, set()) + # For each qualified name, find implementation files + # This handles namespace mismatches (e.g., fs::SDFS vs SDFS) + # Pass header_path to prefer implementations from same directory + impl_files |= find_impl_files_for_qname(qn, ctags_defs_by_qname, header_path) for impl in impl_files: # Skip .ino files - they should never be dependencies of other files if impl.endswith('.ino'): diff --git a/.github/scripts/on-release.sh b/.github/scripts/on-release.sh index e461e77b0c3..dec2723eabb 100755 --- a/.github/scripts/on-release.sh +++ b/.github/scripts/on-release.sh @@ -54,30 +54,6 @@ if [ -n "${VENDOR}" ]; then echo "Setting packager: $VENDOR" fi -function update_version { - set -e - set -o pipefail - - local tag=$1 - local major - local minor - local patch - - # Extract major, minor, and patch from the tag - # We need to make sure to remove the "v" prefix from the tag and any characters after the patch version - tag=$(echo "$tag" | sed 's/^v//g' | sed 's/-.*//g') - major=$(echo "$tag" | cut -d. -f1) - minor=$(echo "$tag" | cut -d. -f2) - patch=$(echo "$tag" | cut -d. -f3 | sed 's/[^0-9].*//') # Remove non-numeric suffixes like RC1, alpha, beta - - echo "Major: $major, Minor: $minor, Patch: $patch" - - "${SCRIPTS_DIR}/update-version.sh" "$major" "$minor" "$patch" - - set +e - set +o pipefail -} - function get_file_size { local file="$1" if [[ "$OSTYPE" == "darwin"* ]]; then @@ -230,7 +206,7 @@ LIBS_ZIP="$PACKAGE_NAME-libs.zip" LIBS_XZ="$PACKAGE_NAME-libs.tar.xz" echo "Updating version..." -if ! update_version "$RELEASE_TAG"; then +if ! "${SCRIPTS_DIR}/update-version.sh" "$RELEASE_TAG"; then echo "ERROR: update_version failed!" exit 1 fi diff --git a/.github/scripts/update-version.sh b/.github/scripts/update-version.sh index 5dd26d9f40a..814cf24afd6 100755 --- a/.github/scripts/update-version.sh +++ b/.github/scripts/update-version.sh @@ -10,23 +10,26 @@ set -o pipefail # "[board].upload.tool=esptool_py" to "[board].upload.tool=esptool_py\n[board].upload.tool.default=esptool_py\n[board].upload.tool.network=esp_ota" #cat boards.txt | sed "s/\([a-zA-Z0-9_\-]*\)\.upload\.tool\=esptool_py/\1\.upload\.tool\=esptool_py\\n\1\.upload\.tool\.default\=esptool_py\\n\1\.upload\.tool\.network\=esp_ota/" -if [ ! $# -eq 3 ]; then +if [ ! $# -eq 1 ]; then echo "Bad number of arguments: $#" >&2 - echo "usage: $0 " >&2 + echo "usage: $0 " >&2 exit 1 fi -re='^[0-9]+$' -if [[ ! $1 =~ $re ]] || [[ ! $2 =~ $re ]] || [[ ! $3 =~ $re ]] ; then - echo "error: Not a valid version: $1.$2.$3" >&2 - echo "usage: $0 " >&2 +# Version must be in the format of X.Y.Z or X.Y.Z-abc123 (POSIX ERE) +re='^[0-9]+\.[0-9]+\.[0-9]+(-[A-Za-z]+[0-9]*)?$' +version=$1 + +if [[ ! $version =~ $re ]] ; then + echo "error: Not a valid version: $version" >&2 + echo "usage: $0 " >&2 exit 1 fi -ESP_ARDUINO_VERSION_MAJOR="$1" -ESP_ARDUINO_VERSION_MINOR="$2" -ESP_ARDUINO_VERSION_PATCH="$3" -ESP_ARDUINO_VERSION="$ESP_ARDUINO_VERSION_MAJOR.$ESP_ARDUINO_VERSION_MINOR.$ESP_ARDUINO_VERSION_PATCH" +ESP_ARDUINO_VERSION_MAJOR=$(echo "$version" | cut -d. -f1) +ESP_ARDUINO_VERSION_MINOR=$(echo "$version" | cut -d. -f2) +ESP_ARDUINO_VERSION_PATCH=$(echo "$version" | cut -d. -f3 | sed 's/[^0-9].*//') # Remove non-numeric suffixes like RC1, alpha, beta +ESP_ARDUINO_VERSION_CLEAN="$ESP_ARDUINO_VERSION_MAJOR.$ESP_ARDUINO_VERSION_MINOR.$ESP_ARDUINO_VERSION_PATCH" # Get ESP-IDF version from build_component.yml (this way we can ensure that the version is correct even if the local libs are not up to date) ESP_IDF_VERSION=$(grep -m 1 "default:" .github/workflows/build_component.yml | sed 's/.*release-v\([^"]*\).*/\1/') @@ -35,38 +38,38 @@ if [ -z "$ESP_IDF_VERSION" ]; then exit 1 fi -echo "New Arduino Version: $ESP_ARDUINO_VERSION" +echo "New Arduino Version: $version" echo "ESP-IDF Version: $ESP_IDF_VERSION" echo "Updating issue template..." -if ! grep -q "v$ESP_ARDUINO_VERSION" .github/ISSUE_TEMPLATE/Issue-report.yml; then +if ! grep -q "v$version" .github/ISSUE_TEMPLATE/Issue-report.yml; then cat .github/ISSUE_TEMPLATE/Issue-report.yml | \ - sed "s/.*\- latest master .*/ - latest master \(checkout manually\)\\n - v$ESP_ARDUINO_VERSION/g" > __issue-report.yml && mv __issue-report.yml .github/ISSUE_TEMPLATE/Issue-report.yml - echo "Issue template updated with version v$ESP_ARDUINO_VERSION" + sed "s/.*\- latest master .*/ - latest master \(checkout manually\)\\n - v$version/g" > __issue-report.yml && mv __issue-report.yml .github/ISSUE_TEMPLATE/Issue-report.yml + echo "Issue template updated with version v$version" else - echo "Version v$ESP_ARDUINO_VERSION already exists in issue template, skipping update" + echo "Version v$version already exists in issue template, skipping update" fi echo "Updating GitLab variables..." cat .gitlab/workflows/common.yml | \ sed "s/ESP_IDF_VERSION:.*/ESP_IDF_VERSION: \"$ESP_IDF_VERSION\"/g" | \ -sed "s/ESP_ARDUINO_VERSION:.*/ESP_ARDUINO_VERSION: \"$ESP_ARDUINO_VERSION\"/g" > .gitlab/workflows/__common.yml && mv .gitlab/workflows/__common.yml .gitlab/workflows/common.yml +sed "s/ESP_ARDUINO_VERSION:.*/ESP_ARDUINO_VERSION: \"$ESP_ARDUINO_VERSION_CLEAN\"/g" > .gitlab/workflows/__common.yml && mv .gitlab/workflows/__common.yml .gitlab/workflows/common.yml echo "Updating platform.txt..." -cat platform.txt | sed "s/version=.*/version=$ESP_ARDUINO_VERSION/g" > __platform.txt && mv __platform.txt platform.txt +cat platform.txt | sed "s/version=.*/version=$ESP_ARDUINO_VERSION_CLEAN/g" > __platform.txt && mv __platform.txt platform.txt echo "Updating package.json..." -cat package.json | sed "s/.*\"version\":.*/ \"version\": \"$ESP_ARDUINO_VERSION\",/g" > __package.json && mv __package.json package.json +cat package.json | sed "s/.*\"version\":.*/ \"version\": \"$ESP_ARDUINO_VERSION_CLEAN\",/g" > __package.json && mv __package.json package.json echo "Updating docs/conf_common.py..." cat docs/conf_common.py | \ -sed "s/.. |version| replace:: .*/.. |version| replace:: $ESP_ARDUINO_VERSION/g" | \ +sed "s/.. |version| replace:: .*/.. |version| replace:: $ESP_ARDUINO_VERSION_CLEAN/g" | \ sed "s/.. |idf_version| replace:: .*/.. |idf_version| replace:: $ESP_IDF_VERSION/g" > docs/__conf_common.py && mv docs/__conf_common.py docs/conf_common.py echo "Updating .gitlab/workflows/common.yml..." cat .gitlab/workflows/common.yml | \ sed "s/ESP_IDF_VERSION:.*/ESP_IDF_VERSION: \"$ESP_IDF_VERSION\"/g" | \ -sed "s/ESP_ARDUINO_VERSION:.*/ESP_ARDUINO_VERSION: \"$ESP_ARDUINO_VERSION\"/g" > .gitlab/workflows/__common.yml && mv .gitlab/workflows/__common.yml .gitlab/workflows/common.yml +sed "s/ESP_ARDUINO_VERSION:.*/ESP_ARDUINO_VERSION: \"$ESP_ARDUINO_VERSION_CLEAN\"/g" > .gitlab/workflows/__common.yml && mv .gitlab/workflows/__common.yml .gitlab/workflows/common.yml echo "Updating cores/esp32/esp_arduino_version.h..." cat cores/esp32/esp_arduino_version.h | \ @@ -78,7 +81,7 @@ libraries=$(find libraries -maxdepth 1 -mindepth 1 -type d -exec basename {} \;) for lib in $libraries; do if [ -f "libraries/$lib/library.properties" ]; then echo "Updating Library $lib..." - cat "libraries/$lib/library.properties" | sed "s/version=.*/version=$ESP_ARDUINO_VERSION/g" > "libraries/$lib/__library.properties" && mv "libraries/$lib/__library.properties" "libraries/$lib/library.properties" + cat "libraries/$lib/library.properties" | sed "s/version=.*/version=$ESP_ARDUINO_VERSION_CLEAN/g" > "libraries/$lib/__library.properties" && mv "libraries/$lib/__library.properties" "libraries/$lib/library.properties" fi done diff --git a/.github/workflows/docs_deploy.yml b/.github/workflows/docs_deploy.yml index 0c54d24aaf9..01eb2b773dc 100644 --- a/.github/workflows/docs_deploy.yml +++ b/.github/workflows/docs_deploy.yml @@ -19,6 +19,7 @@ permissions: jobs: deploy-prod-docs: name: Deploy Documentation on Production + if: github.repository == 'espressif/arduino-esp32' runs-on: ubuntu-22.04 defaults: run: