From c90481f6a5356cbddaae2d461db1fb3982432dd4 Mon Sep 17 00:00:00 2001 From: Raul Marquez <130402456+raul-marquez-csa@users.noreply.github.com> Date: Wed, 13 Mar 2024 21:31:34 -0700 Subject: [PATCH] Matter SDK Doctor (#32554) * Adds Matter SDK Doctor * Fix restyle * Fix restyle * Fix restyle * Fix restyle --- scripts/sdk-doctor/_network.sh | 80 ++++++++++++++++ scripts/sdk-doctor/_os.sh | 69 ++++++++++++++ scripts/sdk-doctor/_repo.sh | 152 ++++++++++++++++++++++++++++++ scripts/sdk-doctor/_version.sh | 27 ++++++ scripts/sdk-doctor/sdk-doctor.sh | 153 +++++++++++++++++++++++++++++++ 5 files changed, 481 insertions(+) create mode 100755 scripts/sdk-doctor/_network.sh create mode 100755 scripts/sdk-doctor/_os.sh create mode 100755 scripts/sdk-doctor/_repo.sh create mode 100755 scripts/sdk-doctor/_version.sh create mode 100755 scripts/sdk-doctor/sdk-doctor.sh diff --git a/scripts/sdk-doctor/_network.sh b/scripts/sdk-doctor/_network.sh new file mode 100755 index 00000000000000..940161ca5c7cea --- /dev/null +++ b/scripts/sdk-doctor/_network.sh @@ -0,0 +1,80 @@ +#!/bin/bash + +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Function to display information for each network interface +display_interface_info() { + interface=$1 + echo "Interface: $interface" + + # Check if interface is up + if ip link show "$interface" | grep -q 'state UP'; then + echo " Status: UP" + else + echo " Status: DOWN" + fi + + # Get and display the IPv4 address + ipv4_address=$(ip -4 addr show "$interface" | grep -oP '(?<=inet\s)\d+(\.\d+){3}') + [ -z "$ipv4_address" ] && ipv4_address="N/A" + echo " IPv4 Address: $ipv4_address" + + # Get and display the IPv6 address + ipv6_address=$(ip -6 addr show "$interface" | grep -oP '(?<=inet6\s)[a-f0-9:]+') + [ -z "$ipv6_address" ] && ipv6_address="N/A" + echo " IPv6 Address: $ipv6_address" + + # Get and display the subnet mask + subnet_mask=$(ifconfig "$interface" | grep -oP '(?<=Mask:)[0-9.]+') + [ -z "$subnet_mask" ] && subnet_mask="N/A" + echo " Subnet Mask: $subnet_mask" + + # Get and display the MAC address + mac_address=$(ip link show "$interface" | grep -oP '(?<=ether\s)[a-f0-9:]+') + [ -z "$mac_address" ] && mac_address="N/A" + echo " MAC Address: $mac_address" +} + +# Get a list of all network interfaces +interfaces=$(ip link show | grep -oP '(?<=^\d: )[e-w]+[0-9a-zA-Z-]+') + +# Iterate over each interface and display relevant information +for intf in "$interfaces"; do + display_interface_info "$intf" + echo "" +done + +# Get and display the default gateway +default_gateway=$(ip route | grep default | awk '{print $3}') +[ -z "$default_gateway" ] && default_gateway="N/A" +echo "Default Gateway: $default_gateway" + +# Get and display the DNS server information +mapfile -t dns_servers < <(grep nameserver /etc/resolv.conf | awk '{print $2}') +if [ ${#dns_servers[@]} -eq 0 ]; then + echo "DNS Servers: N/A" +else + echo "DNS Servers: ${dns_servers[*]}" +fi +echo + +# Check if Internet is available +echo "Checking Internet availability..." +if ping -c 1 8.8.8.8 &>/dev/null; then + echo "Internet is available" +else + echo "Internet is not available" +fi diff --git a/scripts/sdk-doctor/_os.sh b/scripts/sdk-doctor/_os.sh new file mode 100755 index 00000000000000..e22da32e743cfa --- /dev/null +++ b/scripts/sdk-doctor/_os.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ROOT_DIR=$(realpath "$(dirname "$0")"/../..) +cd "$ROOT_DIR" + +# Function to display OS information +get_os_info() { + if [ -f /etc/os-release ]; then + # If available, use /etc/os-release file + . /etc/os-release + echo "Name: $NAME" + echo "Version: $VERSION" + echo "ID: $ID" + echo "ID Like: $ID_LIKE" + elif [ -f /etc/*-release ]; then + # If /etc/os-release is not available, use other available /etc/*-release file + echo "OS Information from /etc/*-release:" + cat /etc/*-release + else + # Print a message if unable to determine OS information + echo "Cannot determine OS information." + fi +} + +# Function to display kernel information +get_kernel_info() { + echo "Kernel Information:" + uname -a | fold -w 88 -s +} + +# Function to display CPU information +get_cpu_info() { + echo "CPU Information:" + lscpu | grep -E "^Architecture:|^CPU op-mode\(s\):|^CPU\(s\):|^Vendor ID:|^Model name:|^CPU max MHz:|^CPU min MHz:" | + sed 's/^[ \t]*//;s/[ \t]*$//' +} + +# Function to display memory information +get_memory_info() { + echo "Memory Information:" + free -h +} + +# Call the functions to display the information +get_os_info +echo + +get_kernel_info +echo + +get_cpu_info +echo + +get_memory_info diff --git a/scripts/sdk-doctor/_repo.sh b/scripts/sdk-doctor/_repo.sh new file mode 100755 index 00000000000000..de619387274117 --- /dev/null +++ b/scripts/sdk-doctor/_repo.sh @@ -0,0 +1,152 @@ +#!/bin/bash + +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ROOT_DIR=$(realpath "$(dirname "$0")"/../..) +cd "$ROOT_DIR" + +get_repo_and_branch_info() { + # Input validation + if [ -z "$1" ]; then + echo "Please provide a path." + return 1 + fi + + path="$1" + repo_friendly_name="Matter SDK" + + if [ "$path" != "." ]; then + title_case_path=$(echo "$path" | awk '{ for(i=1;i<=NF;i++) $i=toupper(substr($i,1,1)) tolower(substr($i,2)); }1') + repo_friendly_name=$title_case_path + fi + + # Check if the directory exists + if [ ! -d "$path" ]; then + echo "Directory '$path' does not exist." + return 1 + fi + + cd "$path" + + # Get the URL of the remote origin + remote_url=$(git config --get remote.origin.url) + + if [ -n "$remote_url" ]; then + # Extract the repository name from the URL + repo_name=$(basename -s .git "$remote_url") + + # Calculate the necessary padding to align the end pipe + total_length=95 # Adjust this based on your frame width + text_length=${#repo_friendly_name}+${#repo_name}+4 # 4 for the ": " and two spaces around the repo name + padding_length=$((total_length - text_length)) + + echo '+-----------------------------------------------------------------------------------------------+' + printf "| %s: %s%*s|\n" "$repo_friendly_name" "$repo_name" "$padding_length" "" + echo '+-----------------------------------------------------------------------------------------------+' + else + # Print error message if there is no remote URL + echo "Not a Git repository or no remote set" + return 1 + fi + + # Get the current branch and its tracking branch + git_status=$(git status) + tracking_branch_info=$(echo "$git_status" | grep "Your branch is up to date with") + + # Extract the fork owner and branch from the tracking branch info + if [[ $tracking_branch_info =~ Your\ branch\ is\ up\ to\ date\ with\ \'([^\']+)\' ]]; then + fork_owner_and_branch="${BASH_REMATCH[1]}" + else + fork_owner_and_branch="Not set or not a tracking branch" + fi + + # Get the commit SHA of the current HEAD + commit_sha=$(git rev-parse HEAD) + echo "Commit SHA: $commit_sha" + + # Get the commit message of the current HEAD + commit_message=$(git log -1 --pretty=format:"%B") + trimmed_commit_message=$(trim_commit_message "$commit_message") + echo "Commit Message: $trimmed_commit_message" + + # Get the commit author of the current HEAD + commit_author=$(git log -1 --pretty=format:"%an") + echo "Commit Author: $commit_author" + + # Get the commit date and time of the current HEAD including timezone + commit_datetime=$(git log -1 --pretty=format:"%cd" --date=format:"%Y-%m-%d %H:%M:%S %z") + echo "Commit Date: $commit_datetime" + + # Attempt to find branches that contain this commit + branches=$(git branch --contains "$commit_sha" | sed 's/^/ /') + + if [ -n "$branches" ]; then + echo "Contained in branches:" + echo "$branches" + else + echo "This commit is not on any known branch." + fi + + echo " Tracking: $fork_owner_and_branch" + + echo + + # Navigate back to the original directory + cd "$ROOT_DIR" +} + +trim_commit_message() { + local commit_message="$1" + + # Check if the commit message contains a newline character + if [[ "$commit_message" == *$'\n'* ]]; then + # Extract the first line of the commit message + local first_line="${commit_message%%$'\n'*}" + else + # If there's no newline, use the entire commit message + local first_line="$commit_message" + fi + + # Trim leading and trailing whitespace from the first line and echo it + echo "$first_line" | sed 's/^[ \t]*//;s/[ \t]*$//' +} + +# Print SDK root git status +get_repo_and_branch_info "." + +# Handle arguments +case "$1" in + --git-sub) + # Initialize an array to hold the directories + declare -a repo_dirs + + cd "$ROOT_DIR" + + # Find directories containing a .github folder and store them in the array, excluding the current directory + while IFS= read -r dir; do + # Check if the directory is not the current directory + if [[ "$dir" != "." ]]; then + repo_dirs+=("$dir") + fi + done < <(find . -type d -name .github | awk -F'/[^/]*$' '{print $1}') + + # Iterate through the directories and call the function for each + for dir in "${repo_dirs[@]}"; do + get_repo_and_branch_info "$dir" + done + ;; + *) ;; +esac diff --git a/scripts/sdk-doctor/_version.sh b/scripts/sdk-doctor/_version.sh new file mode 100755 index 00000000000000..c83f1804b7d46b --- /dev/null +++ b/scripts/sdk-doctor/_version.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +ROOT_DIR=$(realpath "$(dirname "$0")"/../..) +cd "$ROOT_DIR" + +SPEC_VERSION=$(head -n 1 "$ROOT_DIR"/SPECIFICATION_VERSION) +SPEC_SHA=$(head -n 1 "$ROOT_DIR"/data_model/spec_sha) +SCRAPPER_VERSION=$(head -n 1 "$ROOT_DIR"/data_model/scraper_version) + +echo 'SPEC VERSION:' "$SPEC_VERSION" +echo 'SPEC SHA:' "$SPEC_SHA" +echo 'SCRAPER VERSION:' "$SCRAPPER_VERSION" diff --git a/scripts/sdk-doctor/sdk-doctor.sh b/scripts/sdk-doctor/sdk-doctor.sh new file mode 100755 index 00000000000000..597ec81c67fc58 --- /dev/null +++ b/scripts/sdk-doctor/sdk-doctor.sh @@ -0,0 +1,153 @@ +#!/bin/bash + +# +# Copyright (c) 2024 Project CHIP Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +{ + echo " __ __ _ _ _____ _____ _ __ _____ _ " + echo " | \/ | | | | | / ____| __ \| |/ / | __ \ | | " + echo " | \ / | __ _| |_| |_ ___ _ __ | (___ | | | | ' / | | | | ___ ___| |_ ___ _ __ " + echo ' | |\/| |/ _` | __| __/ _ \ `__| \___ \| | | | < | | | |/ _ \ / __| __/ _ \| `__|' + echo " | | | | (_| | |_| || __/ | ____) | |__| | . \ | |__| | (_) | (__| || (_) | | " + echo " |_| |_|\__,_|\__|\__\___|_| |_____/|_____/|_|\_\ |_____/ \___/ \___|\__\___/|_| " + echo " " + + usage() { + echo "Displays Matter SDK setup information." + echo + echo "Usage:" + echo + echo " Show Matter SDK Version, SHA, repository details: $0" + echo " Show Matter SDK git submodule information: $0 --git-sub" + echo " Show Matter SDK host OS system information: $0 --system" + echo " Show all available Matter SDK details: $0 --complete" + echo + } + + width=104 + + # Get the date string + date_string=$(date) + + # Calculate the length of the date string + date_length=${#date_string} + + # Calculate the padding on each side + padding=$(((width - date_length) / 2)) + + # Print spaces for left padding + printf "%${padding}s" + + # Print the date string + echo "$date_string" + echo + + ROOT_DIR=$(realpath "$(dirname "$0")"/../..) + TH_DEV_SCRIPTS_DIR=$ROOT_DIR/scripts/sdk-doctor + cd "$ROOT_DIR" + + # Check for arguments + if [ "$#" -gt 1 ]; then + echo "Error: Too many arguments." + usage + exit 1 + fi + + print_framed_text() { + # Get the text and title from function arguments + input_text="$1" + title="$2" + + # Ensure 'width' is set and has a reasonable value + if [ -z "$width" ] || [ "$width" -lt 10 ]; then + echo "Error: 'width' is not set or too small." + return 1 + fi + + max_line_length=$((width - 6)) # Maximum characters in a line before wrapping + + # Word-wrap the input text + input_text_wrapped=$(echo -e "$input_text" | fold -w "$max_line_length" -s) + + # Calculate height based on the number of lines in the input text + height=$(echo -e "$input_text_wrapped" | wc -l) + height=$((height + 4)) # Add 4 to account for the top and bottom frame borders and inner padding + + # Print the top border with title + title_with_padding=" $title " + title_padding_left=$(((width - 2 - ${#title_with_padding}) / 2)) + [ "$title_padding_left" -lt 0 ] && title_padding_left=0 + title_padding_right=$((width - 2 - ${#title_with_padding} - title_padding_left)) + [ "$title_padding_right" -lt 0 ] && title_padding_right=0 + echo '+'"$(printf "%0.s-" "$(seq 1 "$title_padding_left")")$title_with_padding""$(printf "%0.s-" "$(seq 1 "$title_padding_right")")"'+' + + # Inner top padding + echo "|$(printf ' %.0s' "$(seq 1 $((width - 2)))")|" + + # Print each line of wrapped input text with frame borders and padding + echo -e "$input_text_wrapped" | while IFS= read -r line; do + padding_right=$((width - 4 - ${#line} - 2)) # Subtract 4 for the borders and 2 for the left padding + [ "$padding_right" -lt 0 ] && padding_right=0 + echo "| $line$(printf ' %.0s' "$(seq 1 "$padding_right")") |" + done + + # Inner bottom padding + echo "|$(printf ' %.0s' "$(seq 1 $((width - 2)))")|" + + # Print the bottom border + echo '+'"$(printf "%0.s-" "$(seq 1 $((width - 2)))")"'+' + echo + } + + show_system() { + # OS + os_output=$("$TH_DEV_SCRIPTS_DIR/_os.sh") + print_framed_text "$os_output" "OS" + + # Network + network_output=$("$TH_DEV_SCRIPTS_DIR/_network.sh") + print_framed_text "$network_output" "Network" + } + + # Matter SDK Version + th_version_output=$("$TH_DEV_SCRIPTS_DIR/_version.sh") + print_framed_text "$th_version_output" "Matter SDK Version" + + # Git Status + if [[ "$1" = "--git-sub" ]] || [[ "$1" = "--complete" ]]; then + repository_branches_output=$("$TH_DEV_SCRIPTS_DIR/_repo.sh" "--git-sub") + print_framed_text "$repository_branches_output" "Git Status" + else + repository_branches_output=$("$TH_DEV_SCRIPTS_DIR/_repo.sh" "--git") + print_framed_text "$repository_branches_output" "Git Status" + fi + + # Handle arguments + case "$1" in + --system) + show_system + usage + ;; + --complete) + show_system + usage + ;; + *) + usage + exit 1 + ;; + esac + +} 2>&1 | tee sdk-doctor.txt