From 6baddfe4f3ec43f9e97fe3ff934828c310dcf1b4 Mon Sep 17 00:00:00 2001 From: Edu Date: Wed, 16 Aug 2023 10:19:45 -0300 Subject: [PATCH 01/19] adding script to find unused keys --- package.json | 3 +- scripts/find-unused-keys.sh | 91 +++++++++++++++++++++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100755 scripts/find-unused-keys.sh diff --git a/package.json b/package.json index 00d8c2f027fe..9454f8e982aa 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,8 @@ "analyze-packages": "ANALYZE_BUNDLE=true webpack --config config/webpack/webpack.common.js --env envFile=.env.production", "symbolicate:android": "npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map", "symbolicate:ios": "npx metro-symbolicate main.jsbundle.map", - "test:e2e": "node tests/e2e/testRunner.js --development" + "test:e2e": "node tests/e2e/testRunner.js --development", + "find-missing-keys": "scripts/find-unused-keys.sh" }, "dependencies": { "@expensify/react-native-web": "0.18.15", diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh new file mode 100755 index 000000000000..acfd9be1a191 --- /dev/null +++ b/scripts/find-unused-keys.sh @@ -0,0 +1,91 @@ +#!/bin/bash + +# Configurations +SRC_DIR="src" +STYLES_FILE="src/styles/styles.js" +TRANSLATION_FILES=("src/languages/es.js" "src/languages/en.js") +KEYS_LIST_FILE="keys_list.txt" + +# Function to find and store keys from a file +find_and_store_keys() { + local file="$1" + local file_keys=($(grep -Eo "([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:" "$file" | sed -E "s/[:]//g")) + + for key in "${file_keys[@]}"; do + local line_numbers=($(grep -n "$key" "$file" | cut -d':' -f1)) + for line_number in "${line_numbers[@]}"; do + echo "$key:$file:$line_number" + done + done +} + +# Function to remove keys from the list +remove_keys() { + local file="$1" + local list_file="$2" + + while IFS= read -r key_info; do + local key=$(echo "$key_info" | cut -d':' -f1) + local key_file=$(echo "$key_info" | cut -d':' -f2) + if [[ "$key_file" != "$file" ]]; then + echo "$key_info" + fi + done < "$list_file" +} + +# Function to find unused keys in a file +find_unused_keys_in_file() { + local file="$1" + local list_file="$2" + local unused_keys=() + + while IFS= read -r key_info; do + local key=$(echo "$key_info" | cut -d':' -f1) + local key_file=$(echo "$key_info" | cut -d':' -f2) + local line_number=$(echo "$key_info" | cut -d':' -f3) + if [[ "$key_file" != "$file" ]]; then + continue + fi + + if ! grep -q "$key" "$file"; then + # Check if the line number contains a numeric value + if [[ "$line_number" =~ ^[0-9]+$ ]]; then + unused_keys+=("$key_info") + fi + fi + done < "$list_file" + + for unused_key_info in "${unused_keys[@]}"; do + echo "Error: Unused key '$(echo "$unused_key_info" | cut -d':' -f1)' found in '$file' at line: $(echo "$unused_key_info" | cut -d':' -f3)" + done +} + +# Find and store keys from styles.js (only top-level keys) +grep -Eo "^[[:space:]]*[a-zA-Z0-9_-]+:" "$STYLES_FILE" | sed -E "s/[:]//g" | while IFS= read -r key; do + echo "$key:$STYLES_FILE:0" +done > "$KEYS_LIST_FILE" + +# Find and store keys from translation files +for translation_file in "${TRANSLATION_FILES[@]}"; do + find_and_store_keys "$translation_file" >> "$KEYS_LIST_FILE" +done + +# Find and remove used keys from the list +while IFS= read -r file; do + remove_keys "$file" "$KEYS_LIST_FILE" > keys_list_temp.txt + mv keys_list_temp.txt "$KEYS_LIST_FILE" +done < <(find "$SRC_DIR" -type f) + +# Find unused keys in all files +unused_keys_found=false +while IFS= read -r file; do + unused_keys_in_file=$(find_unused_keys_in_file "$file" "$KEYS_LIST_FILE") + if [[ -n "$unused_keys_in_file" ]]; then + unused_keys_found=true + echo "$unused_keys_in_file" + fi +done < <(find "$SRC_DIR" -type f) + +if [[ "$unused_keys_found" = false ]]; then + echo "No unused keys found." +fi \ No newline at end of file From d798ea6a0a53eb548469a1b6d4a568136de2a6a6 Mon Sep 17 00:00:00 2001 From: Edu Date: Fri, 18 Aug 2023 17:31:12 -0300 Subject: [PATCH 02/19] Separated into 2 functions to find and parse the object names styles and en/es files --- scripts/find-unused-keys.sh | 143 ++++++++++++++++++++---------------- 1 file changed, 78 insertions(+), 65 deletions(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index acfd9be1a191..de13dccba812 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -4,88 +4,101 @@ SRC_DIR="src" STYLES_FILE="src/styles/styles.js" TRANSLATION_FILES=("src/languages/es.js" "src/languages/en.js") -KEYS_LIST_FILE="keys_list.txt" +STYLES_KEYS_FILE="src/languages/style_keys_list_temp.txt" +TRANSLATION_KEYS_FILE="src/languages/translations_keys_list_temp.txt" # Function to find and store keys from a file -find_and_store_keys() { +find_styles_and_store_keys() { local file="$1" - local file_keys=($(grep -Eo "([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:" "$file" | sed -E "s/[:]//g")) - - for key in "${file_keys[@]}"; do - local line_numbers=($(grep -n "$key" "$file" | cut -d':' -f1)) - for line_number in "${line_numbers[@]}"; do - echo "$key:$file:$line_number" - done - done -} + local parent_keys=() + local root_key="" + local line_number=0 # Initialize the line number -# Function to remove keys from the list -remove_keys() { - local file="$1" - local list_file="$2" - - while IFS= read -r key_info; do - local key=$(echo "$key_info" | cut -d':' -f1) - local key_file=$(echo "$key_info" | cut -d':' -f2) - if [[ "$key_file" != "$file" ]]; then - echo "$key_info" + while IFS= read -r line; do + ((line_number++)) # Increment the line number + + # Skip lines that are not key-related + if [[ ! "$line" =~ ^[[:space:]]*const[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\} ]]; then + continue fi - done < "$list_file" + + if [[ "$line" =~ ^[[:space:]]*const[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{ ]]; then + root_key=$(echo "${BASH_REMATCH[1]}" | sed -E "s/[:[:space:]]*\{.*//") + elif [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{ ]]; then + local key=$(echo "$line" | sed -E "s/[:[:space:]]*\{.*//") + # local line_number=$(echo "$line" | grep -n "$key:" | cut -d':' -f1) + + if [[ ${#parent_keys[@]} -gt 0 ]]; then + parent_key_trimmed="${parent_keys[${#parent_keys[@]}-1]// /}" # Trim spaces + key_trimmed="${key// /}" # Trim spaces + key="$parent_key_trimmed.$key_trimmed" + elif [[ -n "$root_key" ]]; then + parent_key_trimmed="${root_key// /}" # Trim spaces + key_trimmed="${key// /}" # Trim spaces + key="$parent_key_trimmed.$key_trimmed" + fi + + echo "$key:$file:$line_number" >> "$STYLES_KEYS_FILE" + parent_keys+=("$key") + elif [[ "$line" =~ ^[[:space:]]*\} ]]; then + # unset "parent_keys[${#parent_keys[@]}-1]" + parent_keys=("${parent_keys[@]:0:${#parent_keys[@]}-1}") + fi + # done < <(grep -E "^[[:space:]]*const[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\}" "$file") + done < "$file" } -# Function to find unused keys in a file -find_unused_keys_in_file() { +find_translations_and_store_keys() { local file="$1" - local list_file="$2" - local unused_keys=() - - while IFS= read -r key_info; do - local key=$(echo "$key_info" | cut -d':' -f1) - local key_file=$(echo "$key_info" | cut -d':' -f2) - local line_number=$(echo "$key_info" | cut -d':' -f3) - if [[ "$key_file" != "$file" ]]; then + local parent_key=() + local current_key="" + local line_number=0 # Initialize the line number + + while IFS= read -r line; do + ((line_number++)) # Increment the line number + + # Skip lines that are not key-related + if [[ ! "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*(\'[^\']*\'|\{)|^[[:space:]]*\} ]]; then continue fi + - if ! grep -q "$key" "$file"; then - # Check if the line number contains a numeric value - if [[ "$line_number" =~ ^[0-9]+$ ]]; then - unused_keys+=("$key_info") + if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*\{ ]]; then + local key="${BASH_REMATCH[1]}" + current_key="$key" + + if [[ ${#parent_keys[@]} -gt 0 ]]; then + local parent_key="${parent_keys[*]}" + current_key="$parent_key.$key" + fi + + parent_keys=("${parent_keys[@]}" "$current_key") + elif [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*(\'[^\']*\'|\{) ]]; then + local key="${BASH_REMATCH[1]}" + # local line_number=$(echo "$line" | grep -n "${BASH_REMATCH[1]}" | cut -d':' -f1) + + if [[ ${#parent_keys[@]} -gt 0 ]]; then + local lastItem="${#parent_keys[@]}-1" + local parent_key="${parent_keys[$lastItem]}" + + echo "${parent_key}.${key}:${file}:${line_number}" >> "$TRANSLATION_KEYS_FILE" + else + echo "$key:${file}:${line_number}" >> "$TRANSLATION_KEYS_FILE" fi + elif [[ "$line" =~ ^[[:space:]]*\} ]]; then + parent_keys=("${parent_keys[@]:0:${#parent_keys[@]}-1}") + current_key="${parent_keys[*]}" fi - done < "$list_file" - - for unused_key_info in "${unused_keys[@]}"; do - echo "Error: Unused key '$(echo "$unused_key_info" | cut -d':' -f1)' found in '$file' at line: $(echo "$unused_key_info" | cut -d':' -f3)" - done + # done < <(grep -E "^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*(\'[^\']*\'|\{)|^[[:space:]]*\}" "$file") + done < "$file" } -# Find and store keys from styles.js (only top-level keys) -grep -Eo "^[[:space:]]*[a-zA-Z0-9_-]+:" "$STYLES_FILE" | sed -E "s/[:]//g" | while IFS= read -r key; do - echo "$key:$STYLES_FILE:0" -done > "$KEYS_LIST_FILE" +# Find and store keys from styles.js +find_styles_and_store_keys "$STYLES_FILE" # Find and store keys from translation files for translation_file in "${TRANSLATION_FILES[@]}"; do - find_and_store_keys "$translation_file" >> "$KEYS_LIST_FILE" + find_translations_and_store_keys "$translation_file" done -# Find and remove used keys from the list -while IFS= read -r file; do - remove_keys "$file" "$KEYS_LIST_FILE" > keys_list_temp.txt - mv keys_list_temp.txt "$KEYS_LIST_FILE" -done < <(find "$SRC_DIR" -type f) - -# Find unused keys in all files -unused_keys_found=false -while IFS= read -r file; do - unused_keys_in_file=$(find_unused_keys_in_file "$file" "$KEYS_LIST_FILE") - if [[ -n "$unused_keys_in_file" ]]; then - unused_keys_found=true - echo "$unused_keys_in_file" - fi -done < <(find "$SRC_DIR" -type f) - -if [[ "$unused_keys_found" = false ]]; then - echo "No unused keys found." -fi \ No newline at end of file +echo "Keys saved to $KEYS_FILE" \ No newline at end of file From 4ff465faced849a23da24f9929793602dc9226b2 Mon Sep 17 00:00:00 2001 From: Edu Date: Mon, 28 Aug 2023 17:12:07 +0200 Subject: [PATCH 03/19] Going through the codebase and get keys from the files --- scripts/find-unused-keys.sh | 50 ++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 6 deletions(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index de13dccba812..f8515ff3e17f 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -4,8 +4,34 @@ SRC_DIR="src" STYLES_FILE="src/styles/styles.js" TRANSLATION_FILES=("src/languages/es.js" "src/languages/en.js") -STYLES_KEYS_FILE="src/languages/style_keys_list_temp.txt" -TRANSLATION_KEYS_FILE="src/languages/translations_keys_list_temp.txt" +STYLES_KEYS_FILE="scripts/style_keys_list_temp.txt" +TRANSLATION_KEYS_FILE="scripts/translations_keys_list_temp.txt" +REMOVAL_KEYS_FILE="scripts/removal_keys_list_temp.txt" + # Create an empty temp file if it doesn't exist + if [ ! -f "$REMOVAL_KEYS_FILE" ]; then + touch "$REMOVAL_KEYS_FILE" + fi +# Function to remove a keyword from the temp file +remove_keyword() { + + keyword="$1" + # echo "Removing $keyword" + grep -v "$keyword" "$STYLES_KEYS_FILE" > "$REMOVAL_KEYS_FILE" + mv "$REMOVAL_KEYS_FILE" "$STYLES_KEYS_FILE" +} + +lookfor_unused_keywords() { + # Loop through all files in the src folder + find src -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do + # echo "Checking $file" + # Search for keywords starting with "styles" + grep -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | while IFS= read -r keyword; do + # Remove any [ ] characters from the keyword + clean_keyword="${keyword//[\[\]]/}" + remove_keyword "$clean_keyword" + done + done +} # Function to find and store keys from a file find_styles_and_store_keys() { @@ -97,8 +123,20 @@ find_translations_and_store_keys() { find_styles_and_store_keys "$STYLES_FILE" # Find and store keys from translation files -for translation_file in "${TRANSLATION_FILES[@]}"; do - find_translations_and_store_keys "$translation_file" -done +# for translation_file in "${TRANSLATION_FILES[@]}"; do +# find_translations_and_store_keys "$translation_file" +# done + +echo "Keys saved to $KEYS_FILE" +echo "Now go through the list and remove the keys that are used." + +line_count=$(wc -l < $STYLES_KEYS_FILE) +echo "Number of lines in the file: $line_count" + +lookfor_unused_keywords + +echo "Unused keys are into to $STYLES_KEYS_FILE" -echo "Keys saved to $KEYS_FILE" \ No newline at end of file +line_count2=$(wc -l < $STYLES_KEYS_FILE) +echo "Number of lines in the file: $line_count2" +# cat "$STYLES_KEYS_FILE" \ No newline at end of file From fd39606656ba36778e293292ecbfd49a5feaa893 Mon Sep 17 00:00:00 2001 From: Edu Date: Tue, 29 Aug 2023 16:30:12 +0200 Subject: [PATCH 04/19] showing unused style keys --- scripts/find-unused-keys.sh | 51 +++++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 5 deletions(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index f8515ff3e17f..38ec0c8b6ed6 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -11,24 +11,58 @@ REMOVAL_KEYS_FILE="scripts/removal_keys_list_temp.txt" if [ ! -f "$REMOVAL_KEYS_FILE" ]; then touch "$REMOVAL_KEYS_FILE" fi + +# Read the style file with unused keys +show_unused_style_keywords() { + while IFS=: read -r key file line_number; do + line_count=$(wc -l < $STYLES_KEYS_FILE) + echo "Unused keys: $line_count" + echo "File: $file" + + # Get lines before and after the error line + lines_before=$((line_number - 3)) + lines_after=$((line_number + 3)) + + # Print context of the error line + echo "Context around line $line_number:" + sed -n "$lines_before,$lines_after p" "$file" | awk -v key="$key" '{gsub(key, "\033[1;31m"key"\033[0m"); print}' + + echo "Unused key: $key" + echo "--------------------------------" + done < "$STYLES_KEYS_FILE" +} + # Function to remove a keyword from the temp file remove_keyword() { keyword="$1" # echo "Removing $keyword" grep -v "$keyword" "$STYLES_KEYS_FILE" > "$REMOVAL_KEYS_FILE" + line_count=$(wc -l < $REMOVAL_KEYS_FILE) + # echo "$REMOVAL_KEYS_FILE lines in the file: $line_count" mv "$REMOVAL_KEYS_FILE" "$STYLES_KEYS_FILE" + # echo "$STYLES_KEYS_FILE UPDATED lines in the file: $line_count" } lookfor_unused_keywords() { # Loop through all files in the src folder - find src -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do + find 'src' -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do # echo "Checking $file" # Search for keywords starting with "styles" - grep -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | while IFS= read -r keyword; do + # grep -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | while IFS= read -r keyword; do + grep -E -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r keyword; do + # Remove any [ ] characters from the keyword + # echo "File: $file" clean_keyword="${keyword//[\[\]]/}" - remove_keyword "$clean_keyword" + # skip styles. keyword that might be used in comments + if [[ "$clean_keyword" == "styles." ]]; then + continue + fi + # echo "Found $clean_keyword" + # Remove the keyword from the temp file + remove_keyword "$clean_keyword" + done done } @@ -64,7 +98,12 @@ find_styles_and_store_keys() { key="$parent_key_trimmed.$key_trimmed" fi - echo "$key:$file:$line_number" >> "$STYLES_KEYS_FILE" + # echo "$key:$file:$line_number" >> "$STYLES_KEYS_FILE" + if [[ "$key" == "styles."* ]]; then + echo "$key:$file:$line_number" >> "$STYLES_KEYS_FILE" + else + echo "styles.$key:$file:$line_number" >> "$STYLES_KEYS_FILE" + fi parent_keys+=("$key") elif [[ "$line" =~ ^[[:space:]]*\} ]]; then # unset "parent_keys[${#parent_keys[@]}-1]" @@ -139,4 +178,6 @@ echo "Unused keys are into to $STYLES_KEYS_FILE" line_count2=$(wc -l < $STYLES_KEYS_FILE) echo "Number of lines in the file: $line_count2" -# cat "$STYLES_KEYS_FILE" \ No newline at end of file +# cat "$STYLES_KEYS_FILE" + +show_unused_style_keywords \ No newline at end of file From d779eecd92326ab69a08bcaee194536412ba7b90 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Fri, 1 Sep 2023 08:05:43 +0200 Subject: [PATCH 05/19] removed translation code --- scripts/find-unused-keys.sh | 84 +++++++------------------------------ 1 file changed, 16 insertions(+), 68 deletions(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index 38ec0c8b6ed6..b99e28d3fe8a 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -3,14 +3,14 @@ # Configurations SRC_DIR="src" STYLES_FILE="src/styles/styles.js" -TRANSLATION_FILES=("src/languages/es.js" "src/languages/en.js") STYLES_KEYS_FILE="scripts/style_keys_list_temp.txt" TRANSLATION_KEYS_FILE="scripts/translations_keys_list_temp.txt" REMOVAL_KEYS_FILE="scripts/removal_keys_list_temp.txt" - # Create an empty temp file if it doesn't exist - if [ ! -f "$REMOVAL_KEYS_FILE" ]; then - touch "$REMOVAL_KEYS_FILE" - fi + +# Create an empty temp file if it doesn't exist +if [ ! -f "$REMOVAL_KEYS_FILE" ]; then + touch "$REMOVAL_KEYS_FILE" +fi # Read the style file with unused keys show_unused_style_keywords() { @@ -34,35 +34,28 @@ show_unused_style_keywords() { # Function to remove a keyword from the temp file remove_keyword() { - keyword="$1" - # echo "Removing $keyword" + grep -v "$keyword" "$STYLES_KEYS_FILE" > "$REMOVAL_KEYS_FILE" line_count=$(wc -l < $REMOVAL_KEYS_FILE) - # echo "$REMOVAL_KEYS_FILE lines in the file: $line_count" mv "$REMOVAL_KEYS_FILE" "$STYLES_KEYS_FILE" - # echo "$STYLES_KEYS_FILE UPDATED lines in the file: $line_count" } lookfor_unused_keywords() { # Loop through all files in the src folder find 'src' -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do - # echo "Checking $file" + # Search for keywords starting with "styles" - # grep -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | while IFS= read -r keyword; do grep -E -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r keyword; do # Remove any [ ] characters from the keyword - # echo "File: $file" clean_keyword="${keyword//[\[\]]/}" # skip styles. keyword that might be used in comments if [[ "$clean_keyword" == "styles." ]]; then continue fi - # echo "Found $clean_keyword" - # Remove the keyword from the temp file - remove_keyword "$clean_keyword" + remove_keyword "$clean_keyword" done done } @@ -87,6 +80,12 @@ find_styles_and_store_keys() { elif [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{ ]]; then local key=$(echo "$line" | sed -E "s/[:[:space:]]*\{.*//") # local line_number=$(echo "$line" | grep -n "$key:" | cut -d':' -f1) + echo "line $line" + # Handle keys defined in functions within objects + function_key_pattern="[a-zA-Z0-9_-]+:[[:space:]]*\\(.*\\)[[:space:]]*=>[[:space:]]*\\{" + if [[ "$line" =~ $function_key_pattern ]]; then + key="${BASH_REMATCH[0]%%:*}" + fi if [[ ${#parent_keys[@]} -gt 0 ]]; then parent_key_trimmed="${parent_keys[${#parent_keys[@]}-1]// /}" # Trim spaces @@ -113,71 +112,20 @@ find_styles_and_store_keys() { done < "$file" } -find_translations_and_store_keys() { - local file="$1" - local parent_key=() - local current_key="" - local line_number=0 # Initialize the line number - - while IFS= read -r line; do - ((line_number++)) # Increment the line number - - # Skip lines that are not key-related - if [[ ! "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*(\'[^\']*\'|\{)|^[[:space:]]*\} ]]; then - continue - fi - - - if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*\{ ]]; then - local key="${BASH_REMATCH[1]}" - current_key="$key" - - if [[ ${#parent_keys[@]} -gt 0 ]]; then - local parent_key="${parent_keys[*]}" - current_key="$parent_key.$key" - fi - - parent_keys=("${parent_keys[@]}" "$current_key") - elif [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*(\'[^\']*\'|\{) ]]; then - local key="${BASH_REMATCH[1]}" - # local line_number=$(echo "$line" | grep -n "${BASH_REMATCH[1]}" | cut -d':' -f1) - - if [[ ${#parent_keys[@]} -gt 0 ]]; then - local lastItem="${#parent_keys[@]}-1" - local parent_key="${parent_keys[$lastItem]}" - - echo "${parent_key}.${key}:${file}:${line_number}" >> "$TRANSLATION_KEYS_FILE" - else - echo "$key:${file}:${line_number}" >> "$TRANSLATION_KEYS_FILE" - fi - elif [[ "$line" =~ ^[[:space:]]*\} ]]; then - parent_keys=("${parent_keys[@]:0:${#parent_keys[@]}-1}") - current_key="${parent_keys[*]}" - fi - # done < <(grep -E "^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+)[[:space:]]*:[[:space:]]*(\'[^\']*\'|\{)|^[[:space:]]*\}" "$file") - done < "$file" -} - # Find and store keys from styles.js find_styles_and_store_keys "$STYLES_FILE" -# Find and store keys from translation files -# for translation_file in "${TRANSLATION_FILES[@]}"; do -# find_translations_and_store_keys "$translation_file" -# done - echo "Keys saved to $KEYS_FILE" echo "Now go through the list and remove the keys that are used." line_count=$(wc -l < $STYLES_KEYS_FILE) echo "Number of lines in the file: $line_count" -lookfor_unused_keywords +# lookfor_unused_keywords echo "Unused keys are into to $STYLES_KEYS_FILE" line_count2=$(wc -l < $STYLES_KEYS_FILE) echo "Number of lines in the file: $line_count2" -# cat "$STYLES_KEYS_FILE" -show_unused_style_keywords \ No newline at end of file +# show_unused_style_keywords \ No newline at end of file From c04114bf72a44cc795e6b537f9d4b2035c8572e7 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Wed, 6 Sep 2023 17:28:19 +0200 Subject: [PATCH 06/19] getting keys from utilities folder to find unused styles --- scripts/find-unused-keys.sh | 131 +++++++++++++++++++++++++++--------- 1 file changed, 99 insertions(+), 32 deletions(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index b99e28d3fe8a..8e00c19dbeef 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -3,8 +3,9 @@ # Configurations SRC_DIR="src" STYLES_FILE="src/styles/styles.js" +UTILITIES_STYLES_FILE="src/styles/utilities" STYLES_KEYS_FILE="scripts/style_keys_list_temp.txt" -TRANSLATION_KEYS_FILE="scripts/translations_keys_list_temp.txt" +UTILITY_STYLES_KEYS_FILE="scripts/utility_keys_list_temp.txt" REMOVAL_KEYS_FILE="scripts/removal_keys_list_temp.txt" # Create an empty temp file if it doesn't exist @@ -35,19 +36,22 @@ show_unused_style_keywords() { # Function to remove a keyword from the temp file remove_keyword() { keyword="$1" - - grep -v "$keyword" "$STYLES_KEYS_FILE" > "$REMOVAL_KEYS_FILE" - line_count=$(wc -l < $REMOVAL_KEYS_FILE) - mv "$REMOVAL_KEYS_FILE" "$STYLES_KEYS_FILE" + if grep -q "$keyword" "$STYLES_KEYS_FILE"; then + grep -v "$keyword" "$STYLES_KEYS_FILE" > "$REMOVAL_KEYS_FILE" + mv "$REMOVAL_KEYS_FILE" "$STYLES_KEYS_FILE" + return 0 # Keyword was removed + else + return 1 # Keyword was not found + fi } lookfor_unused_keywords() { # Loop through all files in the src folder find 'src' -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do - # Search for keywords starting with "styles" - grep -E -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r keyword; do - + # Search for keywords starting with "styles" + grep -E -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r keyword; do + # Remove any [ ] characters from the keyword clean_keyword="${keyword//[\[\]]/}" # skip styles. keyword that might be used in comments @@ -55,8 +59,17 @@ lookfor_unused_keywords() { continue fi - remove_keyword "$clean_keyword" + if ! remove_keyword "$clean_keyword" ; then + # In case of a leaf of the styles object is being used, it meas the parent objects is being used + # we need to mark it as used. + if [[ "$clean_keyword" =~ ^styles\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+$ ]]; then + # Keyword has more than two words, remove words after the second word + keyword_prefix="$(echo "$clean_keyword" | sed -E 's/(styles\.[a-zA-Z0-9_-]+)\..*/\1/')" + remove_keyword "$keyword_prefix" + fi + fi done + done } @@ -70,34 +83,30 @@ find_styles_and_store_keys() { while IFS= read -r line; do ((line_number++)) # Increment the line number - # Skip lines that are not key-related - if [[ ! "$line" =~ ^[[:space:]]*const[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\} ]]; then + # Skip lines that are not key-related + if [[ ! "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\} && ! "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then continue fi - - if [[ "$line" =~ ^[[:space:]]*const[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{ ]]; then - root_key=$(echo "${BASH_REMATCH[1]}" | sed -E "s/[:[:space:]]*\{.*//") - elif [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{ ]]; then + # Handle keys defined in functions within objects + function_key_pattern="^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{" + if [[ "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{ ]]; then + root_key=$(echo "${BASH_REMATCH[2]}" | sed -E "s/[:[:space:]]*\{.*//") + elif [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{ || "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then local key=$(echo "$line" | sed -E "s/[:[:space:]]*\{.*//") - # local line_number=$(echo "$line" | grep -n "$key:" | cut -d':' -f1) - echo "line $line" - # Handle keys defined in functions within objects - function_key_pattern="[a-zA-Z0-9_-]+:[[:space:]]*\\(.*\\)[[:space:]]*=>[[:space:]]*\\{" - if [[ "$line" =~ $function_key_pattern ]]; then + + if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then key="${BASH_REMATCH[0]%%:*}" fi + key="${key// /}" # Trim spaces if [[ ${#parent_keys[@]} -gt 0 ]]; then parent_key_trimmed="${parent_keys[${#parent_keys[@]}-1]// /}" # Trim spaces - key_trimmed="${key// /}" # Trim spaces - key="$parent_key_trimmed.$key_trimmed" + key="$parent_key_trimmed.$key" elif [[ -n "$root_key" ]]; then parent_key_trimmed="${root_key// /}" # Trim spaces - key_trimmed="${key// /}" # Trim spaces - key="$parent_key_trimmed.$key_trimmed" + key="$parent_key_trimmed.$key" fi - # echo "$key:$file:$line_number" >> "$STYLES_KEYS_FILE" if [[ "$key" == "styles."* ]]; then echo "$key:$file:$line_number" >> "$STYLES_KEYS_FILE" else @@ -105,27 +114,85 @@ find_styles_and_store_keys() { fi parent_keys+=("$key") elif [[ "$line" =~ ^[[:space:]]*\} ]]; then - # unset "parent_keys[${#parent_keys[@]}-1]" parent_keys=("${parent_keys[@]:0:${#parent_keys[@]}-1}") fi - # done < <(grep -E "^[[:space:]]*const[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\}" "$file") done < "$file" } +find_utility_styles_store_prefix() { + # Loop through all files in the src folder + find 'src/styles' -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do + + # Search for keywords starting with "styles" + grep -E -o './utilities/[a-zA-Z0-9_-]+' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r keyword; do + variable=$(echo "$keyword" | sed 's/.*\///') + variable_trimmed="${variable// /}" # Trim spaces + + echo "$variable_trimmed" >> "$UTILITY_STYLES_KEYS_FILE" + done + done + + # Sort and remove duplicates from the temporary file + sort -u -o "$UTILITY_STYLES_KEYS_FILE" "$UTILITY_STYLES_KEYS_FILE" +} + +find_utility_usage_as_styles() { + find $UTILITIES_STYLES_FILE -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do + if [ -d "$path" ]; then + # Use the folder name as the root key + root_key=$(basename "$path") + echo "styles.$root_key:$path:0" >> "$STYLES_KEYS_FILE" + continue + fi + find_styles_and_store_keys $file + done +} + +lookfor_unused_utilities() { + # Read each utility keyword from the file + while read -r keyword; do + # Creating a copy so later the replacement can reference it + original_keyword="$keyword" + + # Iterate through all files in "src/styles" + find 'src/styles' -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do + # Find all words that match "$keyword.[a-zA-Z0-9_-]+" + grep -E -o "$original_keyword\.[a-zA-Z0-9_-]+" "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r match; do + # Replace the utility prefix with "styles" + variable=$(echo "$match" | sed "s/^$original_keyword/styles/") + + # Call the remove_keyword function with the variable + remove_keyword "$variable" + done + done + done < "$UTILITY_STYLES_KEYS_FILE" +} + +# Find and store the name of the utility files as keys +find_utility_styles_store_prefix + # Find and store keys from styles.js find_styles_and_store_keys "$STYLES_FILE" +find_utility_usage_as_styles + +# Look for usages of utilities into src/styles +lookfor_unused_utilities + echo "Keys saved to $KEYS_FILE" -echo "Now go through the list and remove the keys that are used." +echo "Now going through the list and removing the keys that are being used." line_count=$(wc -l < $STYLES_KEYS_FILE) -echo "Number of lines in the file: $line_count" +echo "Number of styles found: $line_count" -# lookfor_unused_keywords +lookfor_unused_keywords echo "Unused keys are into to $STYLES_KEYS_FILE" line_count2=$(wc -l < $STYLES_KEYS_FILE) -echo "Number of lines in the file: $line_count2" +echo "Number of styles not being used: $line_count2" + +show_unused_style_keywords -# show_unused_style_keywords \ No newline at end of file +# Delete all files containing a specific pattern in their name +find /scripts -name "*keys_list_temp*" -type f -exec rm -f {} \; \ No newline at end of file From c2ea419b30a93e0a1fa28442dcb6717ed1816744 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Wed, 6 Sep 2023 18:29:24 +0200 Subject: [PATCH 07/19] Code clean up + improvements to the output --- scripts/find-unused-keys.sh | 42 ++++++++++++++++++++++++------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index 8e00c19dbeef..0f713a312197 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -7,30 +7,43 @@ UTILITIES_STYLES_FILE="src/styles/utilities" STYLES_KEYS_FILE="scripts/style_keys_list_temp.txt" UTILITY_STYLES_KEYS_FILE="scripts/utility_keys_list_temp.txt" REMOVAL_KEYS_FILE="scripts/removal_keys_list_temp.txt" + +# FILE_EXTENSIONS="-name '*.js' -o -name '*.jsx' -o -name '*.ts' -o -name '*.tsx'" +FILE_EXTENSIONS=('-name' '*.js' '-o' '-name' '*.jsx' '-o' '-name' '*.ts' '-o' '-name' '*.tsx') + +# trap ctrl-c and call ctrl_c() +trap ctrl_c INT + +function ctrl_c() { + find scripts -name "*keys_list_temp*" -type f -exec rm -f {} \; + exit 1 +} +source scripts/shellUtils.sh + # Create an empty temp file if it doesn't exist -if [ ! -f "$REMOVAL_KEYS_FILE" ]; then - touch "$REMOVAL_KEYS_FILE" -fi +# if [ ! -f "$REMOVAL_KEYS_FILE" ]; then +# touch "$REMOVAL_KEYS_FILE" +# fi # Read the style file with unused keys show_unused_style_keywords() { while IFS=: read -r key file line_number; do - line_count=$(wc -l < $STYLES_KEYS_FILE) - echo "Unused keys: $line_count" - echo "File: $file" + title "File: $file:$line_number" # Get lines before and after the error line lines_before=$((line_number - 3)) lines_after=$((line_number + 3)) # Print context of the error line - echo "Context around line $line_number:" sed -n "$lines_before,$lines_after p" "$file" | awk -v key="$key" '{gsub(key, "\033[1;31m"key"\033[0m"); print}' - echo "Unused key: $key" + error "Unused key: $key" echo "--------------------------------" done < "$STYLES_KEYS_FILE" + + line_count=$(wc -l < $STYLES_KEYS_FILE) + error "Unused keys: $line_count" } # Function to remove a keyword from the temp file @@ -39,6 +52,7 @@ remove_keyword() { if grep -q "$keyword" "$STYLES_KEYS_FILE"; then grep -v "$keyword" "$STYLES_KEYS_FILE" > "$REMOVAL_KEYS_FILE" mv "$REMOVAL_KEYS_FILE" "$STYLES_KEYS_FILE" + return 0 # Keyword was removed else return 1 # Keyword was not found @@ -47,7 +61,7 @@ remove_keyword() { lookfor_unused_keywords() { # Loop through all files in the src folder - find 'src' -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do + find 'src' -type f \( "${FILE_EXTENSIONS[@]}" \) | while read -r file; do # Search for keywords starting with "styles" grep -E -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r keyword; do @@ -121,7 +135,7 @@ find_styles_and_store_keys() { find_utility_styles_store_prefix() { # Loop through all files in the src folder - find 'src/styles' -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do + find 'src/styles' -type f \( "${FILE_EXTENSIONS[@]}" \) | while read -r file; do # Search for keywords starting with "styles" grep -E -o './utilities/[a-zA-Z0-9_-]+' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r keyword; do @@ -137,7 +151,7 @@ find_utility_styles_store_prefix() { } find_utility_usage_as_styles() { - find $UTILITIES_STYLES_FILE -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do + find $UTILITIES_STYLES_FILE -type f \( "${FILE_EXTENSIONS[@]}" \) | while read -r file; do if [ -d "$path" ]; then # Use the folder name as the root key root_key=$(basename "$path") @@ -155,7 +169,7 @@ lookfor_unused_utilities() { original_keyword="$keyword" # Iterate through all files in "src/styles" - find 'src/styles' -type f -name "*.js" -o -name "*.jsx" -o -name "*.ts" -o -name "*.tsx" | while read -r file; do + find 'src/styles' -type f \( "${FILE_EXTENSIONS[@]}" \) | while read -r file; do # Find all words that match "$keyword.[a-zA-Z0-9_-]+" grep -E -o "$original_keyword\.[a-zA-Z0-9_-]+" "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r match; do # Replace the utility prefix with "styles" @@ -194,5 +208,5 @@ echo "Number of styles not being used: $line_count2" show_unused_style_keywords -# Delete all files containing a specific pattern in their name -find /scripts -name "*keys_list_temp*" -type f -exec rm -f {} \; \ No newline at end of file +# Delete all temo files +find scripts -name "*keys_list_temp*" -type f -exec rm -f {} \; \ No newline at end of file From 3042c9abe0fa3f3bab4bb0fb97a1c8c039f748c7 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Thu, 7 Sep 2023 16:15:53 +0200 Subject: [PATCH 08/19] Clean up, used builtins and improved code readability --- scripts/find-unused-keys.sh | 165 +++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 77 deletions(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index 0f713a312197..b24b4c1150e2 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -1,30 +1,41 @@ #!/bin/bash # Configurations -SRC_DIR="src" -STYLES_FILE="src/styles/styles.js" -UTILITIES_STYLES_FILE="src/styles/utilities" -STYLES_KEYS_FILE="scripts/style_keys_list_temp.txt" -UTILITY_STYLES_KEYS_FILE="scripts/utility_keys_list_temp.txt" -REMOVAL_KEYS_FILE="scripts/removal_keys_list_temp.txt" +readonly SRC_DIR="src" +readonly STYLES_FILE="src/styles/styles.js" +readonly UTILITIES_STYLES_FILE="src/styles/utilities" +readonly STYLES_KEYS_FILE="scripts/style_keys_list_temp.txt" +readonly UTILITY_STYLES_KEYS_FILE="scripts/utility_keys_list_temp.txt" +readonly REMOVAL_KEYS_FILE="scripts/removal_keys_list_temp.txt" +readonly AMOUNT_LINES_TO_SHOW=3 + +readonly FILE_EXTENSIONS=('-name' '*.js' '-o' '-name' '*.jsx' '-o' '-name' '*.ts' '-o' '-name' '*.tsx') + +# Regex +readonly OBJ_PROP_DECLARATION_REGEX="^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\}" +readonly OBJ_PROP_FUNC_DEFINITION_REGEX="^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\} && ! [[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{" +readonly OBJ_DEFINITION_REGEX="^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{" +readonly CAPTURE_ARROW_FUNC_REGEX='^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{' +readonly CAPTURE_OBJ_ARROW_FUNC_REGEX='^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{' -# FILE_EXTENSIONS="-name '*.js' -o -name '*.jsx' -o -name '*.ts' -o -name '*.tsx'" -FILE_EXTENSIONS=('-name' '*.js' '-o' '-name' '*.jsx' '-o' '-name' '*.ts' '-o' '-name' '*.tsx') +source scripts/shellUtils.sh # trap ctrl-c and call ctrl_c() trap ctrl_c INT -function ctrl_c() { +delete_temp_files() { find scripts -name "*keys_list_temp*" -type f -exec rm -f {} \; +} + +ctrl_c() { + delete_temp_files exit 1 } -source scripts/shellUtils.sh - -# Create an empty temp file if it doesn't exist -# if [ ! -f "$REMOVAL_KEYS_FILE" ]; then -# touch "$REMOVAL_KEYS_FILE" -# fi +count_lines() { + local file=$1 + wc -l < $file +} # Read the style file with unused keys show_unused_style_keywords() { @@ -32,23 +43,29 @@ show_unused_style_keywords() { title "File: $file:$line_number" # Get lines before and after the error line - lines_before=$((line_number - 3)) - lines_after=$((line_number + 3)) - - # Print context of the error line - sed -n "$lines_before,$lines_after p" "$file" | awk -v key="$key" '{gsub(key, "\033[1;31m"key"\033[0m"); print}' + local lines_before=$((line_number - AMOUNT_LINES_TO_SHOW)) + local lines_after=$((line_number + AMOUNT_LINES_TO_SHOW)) + # Read the lines into an array + local lines=() + while IFS= read -r line; do + lines+=("$line") + done < "$file" + + # Loop through the lines + for ((i = lines_before; i <= lines_after; i++)); do + local line="${lines[i]}" + # Print context of the error line + echo "$line" + done error "Unused key: $key" echo "--------------------------------" done < "$STYLES_KEYS_FILE" - - line_count=$(wc -l < $STYLES_KEYS_FILE) - error "Unused keys: $line_count" } # Function to remove a keyword from the temp file remove_keyword() { - keyword="$1" + local keyword="$1" if grep -q "$keyword" "$STYLES_KEYS_FILE"; then grep -v "$keyword" "$STYLES_KEYS_FILE" > "$REMOVAL_KEYS_FILE" mv "$REMOVAL_KEYS_FILE" "$STYLES_KEYS_FILE" @@ -61,13 +78,13 @@ remove_keyword() { lookfor_unused_keywords() { # Loop through all files in the src folder - find 'src' -type f \( "${FILE_EXTENSIONS[@]}" \) | while read -r file; do + while read -r file; do # Search for keywords starting with "styles" - grep -E -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r keyword; do + while IFS= read -r keyword; do # Remove any [ ] characters from the keyword - clean_keyword="${keyword//[\[\]]/}" + local clean_keyword="${keyword//[\[\]]/}" # skip styles. keyword that might be used in comments if [[ "$clean_keyword" == "styles." ]]; then continue @@ -78,46 +95,41 @@ lookfor_unused_keywords() { # we need to mark it as used. if [[ "$clean_keyword" =~ ^styles\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+$ ]]; then # Keyword has more than two words, remove words after the second word - keyword_prefix="$(echo "$clean_keyword" | sed -E 's/(styles\.[a-zA-Z0-9_-]+)\..*/\1/')" + local keyword_prefix="${clean_keyword%.*}" remove_keyword "$keyword_prefix" fi fi - done - - done + done < <(grep -E -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/') + done < <(find 'src' -type f \( "${FILE_EXTENSIONS[@]}" \)) } + # Function to find and store keys from a file find_styles_and_store_keys() { local file="$1" local parent_keys=() local root_key="" - local line_number=0 # Initialize the line number + local line_number=0 while IFS= read -r line; do - ((line_number++)) # Increment the line number + ((line_number++)) # Skip lines that are not key-related - if [[ ! "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\} && ! "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then + if [[ ! "$line" =~ $OBJ_PROP_DECLARATION_REGEX && ! "$line" =~ $CAPTURE_ARROW_FUNC_REGEX ]]; then continue fi - # Handle keys defined in functions within objects - function_key_pattern="^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{" - if [[ "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{ ]]; then - root_key=$(echo "${BASH_REMATCH[2]}" | sed -E "s/[:[:space:]]*\{.*//") - elif [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{ || "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then - local key=$(echo "$line" | sed -E "s/[:[:space:]]*\{.*//") - - if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then - key="${BASH_REMATCH[0]%%:*}" - fi - + + if [[ "$line" =~ $OBJ_DEFINITION_REGEX ]]; then + root_key="${BASH_REMATCH[2]%%:*{*)}" + elif [[ "$line" =~ $CAPTURE_OBJ_ARROW_FUNC_REGEX ]]; then + # Removing all the extra lines after the ":" + local key="${line%%:*}" key="${key// /}" # Trim spaces if [[ ${#parent_keys[@]} -gt 0 ]]; then - parent_key_trimmed="${parent_keys[${#parent_keys[@]}-1]// /}" # Trim spaces + local parent_key_trimmed="${parent_keys[${#parent_keys[@]}-1]// /}" # Trim spaces key="$parent_key_trimmed.$key" elif [[ -n "$root_key" ]]; then - parent_key_trimmed="${root_key// /}" # Trim spaces + local parent_key_trimmed="${root_key// /}" # Trim spaces key="$parent_key_trimmed.$key" fi @@ -135,50 +147,49 @@ find_styles_and_store_keys() { find_utility_styles_store_prefix() { # Loop through all files in the src folder - find 'src/styles' -type f \( "${FILE_EXTENSIONS[@]}" \) | while read -r file; do - + while read -r file; do # Search for keywords starting with "styles" - grep -E -o './utilities/[a-zA-Z0-9_-]+' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r keyword; do - variable=$(echo "$keyword" | sed 's/.*\///') - variable_trimmed="${variable// /}" # Trim spaces + while IFS= read -r keyword; do + local variable="${keyword##*/}" + local variable_trimmed="${variable// /}" # Trim spaces echo "$variable_trimmed" >> "$UTILITY_STYLES_KEYS_FILE" - done - done + done < <(grep -E -o './utilities/[a-zA-Z0-9_-]+' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/') + done < <(find 'src/styles' -type f \( "${FILE_EXTENSIONS[@]}" \)) # Sort and remove duplicates from the temporary file sort -u -o "$UTILITY_STYLES_KEYS_FILE" "$UTILITY_STYLES_KEYS_FILE" } find_utility_usage_as_styles() { - find $UTILITIES_STYLES_FILE -type f \( "${FILE_EXTENSIONS[@]}" \) | while read -r file; do + while read -r file; do if [ -d "$path" ]; then # Use the folder name as the root key - root_key=$(basename "$path") + local root_key=$(basename "$path") echo "styles.$root_key:$path:0" >> "$STYLES_KEYS_FILE" continue fi find_styles_and_store_keys $file - done + done < <(find $UTILITIES_STYLES_FILE -type f \( "${FILE_EXTENSIONS[@]}" \)) } lookfor_unused_utilities() { # Read each utility keyword from the file while read -r keyword; do # Creating a copy so later the replacement can reference it - original_keyword="$keyword" + local original_keyword="$keyword" # Iterate through all files in "src/styles" - find 'src/styles' -type f \( "${FILE_EXTENSIONS[@]}" \) | while read -r file; do + while read -r file; do # Find all words that match "$keyword.[a-zA-Z0-9_-]+" - grep -E -o "$original_keyword\.[a-zA-Z0-9_-]+" "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/' | while IFS= read -r match; do + while IFS= read -r match; do # Replace the utility prefix with "styles" - variable=$(echo "$match" | sed "s/^$original_keyword/styles/") + local variable="${match/#$original_keyword/styles}" # Call the remove_keyword function with the variable remove_keyword "$variable" - done - done + done < <(grep -E -o "$original_keyword\.[a-zA-Z0-9_-]+" "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/') + done < <(find 'src/styles' -type f \( "${FILE_EXTENSIONS[@]}" \)) done < "$UTILITY_STYLES_KEYS_FILE" } @@ -193,20 +204,20 @@ find_utility_usage_as_styles # Look for usages of utilities into src/styles lookfor_unused_utilities -echo "Keys saved to $KEYS_FILE" -echo "Now going through the list and removing the keys that are being used." - -line_count=$(wc -l < $STYLES_KEYS_FILE) -echo "Number of styles found: $line_count" +echo "⏱️ Now going through the list and looking for unused keys." lookfor_unused_keywords -echo "Unused keys are into to $STYLES_KEYS_FILE" - -line_count2=$(wc -l < $STYLES_KEYS_FILE) -echo "Number of styles not being used: $line_count2" - -show_unused_style_keywords - -# Delete all temo files -find scripts -name "*keys_list_temp*" -type f -exec rm -f {} \; \ No newline at end of file +final_styles_line_count=$(count_lines "$STYLES_KEYS_FILE") + +if [[ $final_styles_line_count -eq 0 ]]; then + # Exit successfully (status code 0) + delete_temp_files + success "Styles are in a good shape" + exit 0 +else + show_unused_style_keywords + delete_temp_files + error "Unused keys: $final_styles_line_count" + exit 1 +fi \ No newline at end of file From 6fa51d0bbbfe9b244a7c7732b8b9ac3f1c8d835e Mon Sep 17 00:00:00 2001 From: Eduardo Date: Thu, 7 Sep 2023 18:09:34 +0200 Subject: [PATCH 09/19] Fixed lint issues --- scripts/find-unused-keys.sh | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index b24b4c1150e2..568e3f7045d2 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -13,10 +13,9 @@ readonly FILE_EXTENSIONS=('-name' '*.js' '-o' '-name' '*.jsx' '-o' '-name' '*.ts # Regex readonly OBJ_PROP_DECLARATION_REGEX="^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\}" -readonly OBJ_PROP_FUNC_DEFINITION_REGEX="^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\} && ! [[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{" readonly OBJ_DEFINITION_REGEX="^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{" -readonly CAPTURE_ARROW_FUNC_REGEX='^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{' -readonly CAPTURE_OBJ_ARROW_FUNC_REGEX='^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{' +readonly CAPTURE_ARROW_FUNC_REGEX="^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{" +readonly CAPTURE_OBJ_ARROW_FUNC_REGEX="^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{" source scripts/shellUtils.sh @@ -27,6 +26,7 @@ delete_temp_files() { find scripts -name "*keys_list_temp*" -type f -exec rm -f {} \; } +# shellcheck disable=SC2317 # Don't warn about unreachable commands in this function ctrl_c() { delete_temp_files exit 1 @@ -34,7 +34,7 @@ ctrl_c() { count_lines() { local file=$1 - wc -l < $file + wc -l < "$file" } # Read the style file with unused keys @@ -100,7 +100,7 @@ lookfor_unused_keywords() { fi fi done < <(grep -E -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/') - done < <(find 'src' -type f \( "${FILE_EXTENSIONS[@]}" \)) + done < <(find $SRC_DIR -type f \( "${FILE_EXTENSIONS[@]}" \)) } @@ -163,13 +163,13 @@ find_utility_styles_store_prefix() { find_utility_usage_as_styles() { while read -r file; do - if [ -d "$path" ]; then + if [ -d "$file" ]; then # Use the folder name as the root key - local root_key=$(basename "$path") + local root_key=$(basename "$file") echo "styles.$root_key:$path:0" >> "$STYLES_KEYS_FILE" continue fi - find_styles_and_store_keys $file + find_styles_and_store_keys "$file" done < <(find $UTILITIES_STYLES_FILE -type f \( "${FILE_EXTENSIONS[@]}" \)) } From 3424140f511f65020540ce5d7ca88b5ca49ce50f Mon Sep 17 00:00:00 2001 From: Eduardo Date: Thu, 7 Sep 2023 18:12:11 +0200 Subject: [PATCH 10/19] typo fixed --- scripts/find-unused-keys.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index 568e3f7045d2..f492f43a5233 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -91,7 +91,7 @@ lookfor_unused_keywords() { fi if ! remove_keyword "$clean_keyword" ; then - # In case of a leaf of the styles object is being used, it meas the parent objects is being used + # In case of a leaf of the styles object is being used, it means the parent objects is being used # we need to mark it as used. if [[ "$clean_keyword" =~ ^styles\.[a-zA-Z0-9_-]+\.[a-zA-Z0-9_-]+$ ]]; then # Keyword has more than two words, remove words after the second word From ac8aea27d87efac1766ac5fc552d9c798736942a Mon Sep 17 00:00:00 2001 From: Eduardo Date: Fri, 8 Sep 2023 11:59:01 +0200 Subject: [PATCH 11/19] fixed some lint errors + clean ups --- scripts/find-unused-keys.sh | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index f492f43a5233..2bb0c8200aa0 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -107,6 +107,7 @@ lookfor_unused_keywords() { # Function to find and store keys from a file find_styles_and_store_keys() { local file="$1" + local base_name="${2:-styles}" # Set styles as default local parent_keys=() local root_key="" local line_number=0 @@ -134,9 +135,9 @@ find_styles_and_store_keys() { fi if [[ "$key" == "styles."* ]]; then - echo "$key:$file:$line_number" >> "$STYLES_KEYS_FILE" + echo "${key}:${file}:${line_number}" >> "$STYLES_KEYS_FILE" else - echo "styles.$key:$file:$line_number" >> "$STYLES_KEYS_FILE" + echo "styles.${key}|${base_name}.${key}:${file}:${line_number}" >> "$STYLES_KEYS_FILE" fi parent_keys+=("$key") elif [[ "$line" =~ ^[[:space:]]*\} ]]; then @@ -158,18 +159,24 @@ find_utility_styles_store_prefix() { done < <(find 'src/styles' -type f \( "${FILE_EXTENSIONS[@]}" \)) # Sort and remove duplicates from the temporary file - sort -u -o "$UTILITY_STYLES_KEYS_FILE" "$UTILITY_STYLES_KEYS_FILE" + sort -u -o "${UTILITY_STYLES_KEYS_FILE}" "${UTILITY_STYLES_KEYS_FILE}" } find_utility_usage_as_styles() { while read -r file; do - if [ -d "$file" ]; then - # Use the folder name as the root key - local root_key=$(basename "$file") - echo "styles.$root_key:$path:0" >> "$STYLES_KEYS_FILE" + local folder_name + local root_key + local parent_dir + + # Get the folder name, given this utility files are index.js + parent_dir=$(dirname "$file") + root_key=$(basename "${parent_dir}") + + if [[ "${root_key}" == "utilities" ]]; then continue fi - find_styles_and_store_keys "$file" + + find_styles_and_store_keys "${file}" "${root_key}" done < <(find $UTILITIES_STYLES_FILE -type f \( "${FILE_EXTENSIONS[@]}" \)) } @@ -177,7 +184,7 @@ lookfor_unused_utilities() { # Read each utility keyword from the file while read -r keyword; do # Creating a copy so later the replacement can reference it - local original_keyword="$keyword" + local original_keyword="${keyword}" # Iterate through all files in "src/styles" while read -r file; do @@ -185,9 +192,9 @@ lookfor_unused_utilities() { while IFS= read -r match; do # Replace the utility prefix with "styles" local variable="${match/#$original_keyword/styles}" - # Call the remove_keyword function with the variable - remove_keyword "$variable" + remove_keyword "${variable}" + remove_keyword "${match}" done < <(grep -E -o "$original_keyword\.[a-zA-Z0-9_-]+" "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/') done < <(find 'src/styles' -type f \( "${FILE_EXTENSIONS[@]}" \)) done < "$UTILITY_STYLES_KEYS_FILE" From ff2174b06790a1f974d14b1037b35005403152d0 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Fri, 8 Sep 2023 15:25:29 +0200 Subject: [PATCH 12/19] removed unused variable --- scripts/find-unused-keys.sh | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/find-unused-keys.sh b/scripts/find-unused-keys.sh index 2bb0c8200aa0..5dff65571d54 100755 --- a/scripts/find-unused-keys.sh +++ b/scripts/find-unused-keys.sh @@ -164,7 +164,6 @@ find_utility_styles_store_prefix() { find_utility_usage_as_styles() { while read -r file; do - local folder_name local root_key local parent_dir From 261adb0db8db5ea80b67f78b060738380b72d5eb Mon Sep 17 00:00:00 2001 From: Eduardo Date: Mon, 11 Sep 2023 16:18:36 +0200 Subject: [PATCH 13/19] moved unused style script into workflow actions --- .../scripts/findUnusedKeys.sh | 22 +++++++++++-------- .github/workflows/findUnusedStyles.yml | 22 +++++++++++++++++++ package.json | 2 +- 3 files changed, 36 insertions(+), 10 deletions(-) rename scripts/find-unused-keys.sh => .github/scripts/findUnusedKeys.sh (90%) create mode 100644 .github/workflows/findUnusedStyles.yml diff --git a/scripts/find-unused-keys.sh b/.github/scripts/findUnusedKeys.sh similarity index 90% rename from scripts/find-unused-keys.sh rename to .github/scripts/findUnusedKeys.sh index 5dff65571d54..1ab00662dfe7 100755 --- a/scripts/find-unused-keys.sh +++ b/.github/scripts/findUnusedKeys.sh @@ -1,12 +1,16 @@ #!/bin/bash # Configurations -readonly SRC_DIR="src" -readonly STYLES_FILE="src/styles/styles.js" -readonly UTILITIES_STYLES_FILE="src/styles/utilities" -readonly STYLES_KEYS_FILE="scripts/style_keys_list_temp.txt" -readonly UTILITY_STYLES_KEYS_FILE="scripts/utility_keys_list_temp.txt" -readonly REMOVAL_KEYS_FILE="scripts/removal_keys_list_temp.txt" +declare LIB_PATH +LIB_PATH="$(cd "$(dirname "${BASH_SOURCE[0]}")" && cd ../../ && pwd)" + +readonly SRC_DIR="${LIB_PATH}/src" +readonly STYLES_DIR="${LIB_PATH}/src/styles" +readonly STYLES_FILE="${LIB_PATH}/src/styles/styles.js" +readonly UTILITIES_STYLES_FILE="${LIB_PATH}/src/styles/utilities" +readonly STYLES_KEYS_FILE="${LIB_PATH}/scripts/style_keys_list_temp.txt" +readonly UTILITY_STYLES_KEYS_FILE="${LIB_PATH}/scripts/utility_keys_list_temp.txt" +readonly REMOVAL_KEYS_FILE="${LIB_PATH}/scripts/removal_keys_list_temp.txt" readonly AMOUNT_LINES_TO_SHOW=3 readonly FILE_EXTENSIONS=('-name' '*.js' '-o' '-name' '*.jsx' '-o' '-name' '*.ts' '-o' '-name' '*.tsx') @@ -23,7 +27,7 @@ source scripts/shellUtils.sh trap ctrl_c INT delete_temp_files() { - find scripts -name "*keys_list_temp*" -type f -exec rm -f {} \; + find "${LIB_PATH}/scripts" -name "*keys_list_temp*" -type f -exec rm -f {} \; } # shellcheck disable=SC2317 # Don't warn about unreachable commands in this function @@ -156,7 +160,7 @@ find_utility_styles_store_prefix() { echo "$variable_trimmed" >> "$UTILITY_STYLES_KEYS_FILE" done < <(grep -E -o './utilities/[a-zA-Z0-9_-]+' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/') - done < <(find 'src/styles' -type f \( "${FILE_EXTENSIONS[@]}" \)) + done < <(find $STYLES_DIR -type f \( "${FILE_EXTENSIONS[@]}" \)) # Sort and remove duplicates from the temporary file sort -u -o "${UTILITY_STYLES_KEYS_FILE}" "${UTILITY_STYLES_KEYS_FILE}" @@ -195,7 +199,7 @@ lookfor_unused_utilities() { remove_keyword "${variable}" remove_keyword "${match}" done < <(grep -E -o "$original_keyword\.[a-zA-Z0-9_-]+" "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/') - done < <(find 'src/styles' -type f \( "${FILE_EXTENSIONS[@]}" \)) + done < <(find $STYLES_DIR -type f \( "${FILE_EXTENSIONS[@]}" \)) done < "$UTILITY_STYLES_KEYS_FILE" } diff --git a/.github/workflows/findUnusedStyles.yml b/.github/workflows/findUnusedStyles.yml new file mode 100644 index 000000000000..b832084dcc7e --- /dev/null +++ b/.github/workflows/findUnusedStyles.yml @@ -0,0 +1,22 @@ +name: Find Unused styles + +on: + pull_request: + types: [opened, synchronize] + branches-ignore: [staging, production] + +jobs: + perf-tests: + if: ${{ github.actor != 'OSBotify' }} + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup NodeJS + uses: Expensify/App/.github/actions/composite/setupNode@main + + - name: Run unused style searcher + shell: bash + run: ./.github/scripts/findUnusedKeys.sh + diff --git a/package.json b/package.json index 9baff5b8f0b1..391e32f40029 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "symbolicate:android": "npx metro-symbolicate android/app/build/generated/sourcemaps/react/release/index.android.bundle.map", "symbolicate:ios": "npx metro-symbolicate main.jsbundle.map", "test:e2e": "node tests/e2e/testRunner.js --development", - "find-missing-keys": "scripts/find-unused-keys.sh" + "gh-actions-unused-styles": "./.github/scripts/findUnusedKeys.sh" }, "dependencies": { "@expensify/react-native-web": "0.18.15", From 82cf6262896e84c37ee761e47e25b94c6632373a Mon Sep 17 00:00:00 2001 From: Eduardo Date: Mon, 11 Sep 2023 16:30:37 +0200 Subject: [PATCH 14/19] added find unused styles into lint.yml workflow --- .github/workflows/findUnusedStyles.yml | 22 ---------------------- .github/workflows/lint.yml | 4 ++++ 2 files changed, 4 insertions(+), 22 deletions(-) delete mode 100644 .github/workflows/findUnusedStyles.yml diff --git a/.github/workflows/findUnusedStyles.yml b/.github/workflows/findUnusedStyles.yml deleted file mode 100644 index b832084dcc7e..000000000000 --- a/.github/workflows/findUnusedStyles.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Find Unused styles - -on: - pull_request: - types: [opened, synchronize] - branches-ignore: [staging, production] - -jobs: - perf-tests: - if: ${{ github.actor != 'OSBotify' }} - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Setup NodeJS - uses: Expensify/App/.github/actions/composite/setupNode@main - - - name: Run unused style searcher - shell: bash - run: ./.github/scripts/findUnusedKeys.sh - diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 795271cab60a..7158d4f67e7b 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -31,3 +31,7 @@ jobs: echo 'Error: Prettier diff detected! Please run `npm run prettier` and commit the changes.' exit 1 fi + + - name: Run unused style searcher + shell: bash + run: ./.github/scripts/findUnusedKeys.sh From d47feeee66e09807971ccd055333bb97e0de19ea Mon Sep 17 00:00:00 2001 From: Eduardo Date: Mon, 11 Sep 2023 16:39:04 +0200 Subject: [PATCH 15/19] fixed some lint issues --- .github/scripts/findUnusedKeys.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/scripts/findUnusedKeys.sh b/.github/scripts/findUnusedKeys.sh index 1ab00662dfe7..0dbd5c033d5f 100755 --- a/.github/scripts/findUnusedKeys.sh +++ b/.github/scripts/findUnusedKeys.sh @@ -104,7 +104,7 @@ lookfor_unused_keywords() { fi fi done < <(grep -E -o '\bstyles\.[a-zA-Z0-9_.]*' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/') - done < <(find $SRC_DIR -type f \( "${FILE_EXTENSIONS[@]}" \)) + done < <(find "${SRC_DIR}" -type f \( "${FILE_EXTENSIONS[@]}" \)) } @@ -160,7 +160,7 @@ find_utility_styles_store_prefix() { echo "$variable_trimmed" >> "$UTILITY_STYLES_KEYS_FILE" done < <(grep -E -o './utilities/[a-zA-Z0-9_-]+' "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/') - done < <(find $STYLES_DIR -type f \( "${FILE_EXTENSIONS[@]}" \)) + done < <(find "${STYLES_DIR}" -type f \( "${FILE_EXTENSIONS[@]}" \)) # Sort and remove duplicates from the temporary file sort -u -o "${UTILITY_STYLES_KEYS_FILE}" "${UTILITY_STYLES_KEYS_FILE}" @@ -180,7 +180,7 @@ find_utility_usage_as_styles() { fi find_styles_and_store_keys "${file}" "${root_key}" - done < <(find $UTILITIES_STYLES_FILE -type f \( "${FILE_EXTENSIONS[@]}" \)) + done < <(find "${UTILITIES_STYLES_FILE}" -type f \( "${FILE_EXTENSIONS[@]}" \)) } lookfor_unused_utilities() { @@ -199,7 +199,7 @@ lookfor_unused_utilities() { remove_keyword "${variable}" remove_keyword "${match}" done < <(grep -E -o "$original_keyword\.[a-zA-Z0-9_-]+" "$file" | grep -v '\/\/' | grep -vE '\/\*.*\*\/') - done < <(find $STYLES_DIR -type f \( "${FILE_EXTENSIONS[@]}" \)) + done < <(find "${STYLES_DIR}" -type f \( "${FILE_EXTENSIONS[@]}" \)) done < "$UTILITY_STYLES_KEYS_FILE" } From ebf2e6683d3f019a8549984c72befd534c553401 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Tue, 12 Sep 2023 20:24:16 +0200 Subject: [PATCH 16/19] Improved script find objects and fields with arrow function on different moments, removed unused styles --- .github/scripts/findUnusedKeys.sh | 83 ++++++-- src/styles/styles.js | 336 +----------------------------- 2 files changed, 67 insertions(+), 352 deletions(-) diff --git a/.github/scripts/findUnusedKeys.sh b/.github/scripts/findUnusedKeys.sh index 0dbd5c033d5f..85d8112e8f13 100755 --- a/.github/scripts/findUnusedKeys.sh +++ b/.github/scripts/findUnusedKeys.sh @@ -15,12 +15,6 @@ readonly AMOUNT_LINES_TO_SHOW=3 readonly FILE_EXTENSIONS=('-name' '*.js' '-o' '-name' '*.jsx' '-o' '-name' '*.ts' '-o' '-name' '*.tsx') -# Regex -readonly OBJ_PROP_DECLARATION_REGEX="^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\}" -readonly OBJ_DEFINITION_REGEX="^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{" -readonly CAPTURE_ARROW_FUNC_REGEX="^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{" -readonly CAPTURE_OBJ_ARROW_FUNC_REGEX="^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{" - source scripts/shellUtils.sh # trap ctrl-c and call ctrl_c() @@ -38,7 +32,11 @@ ctrl_c() { count_lines() { local file=$1 - wc -l < "$file" + if [[ -e "$file" ]]; then + wc -l < "$file" + else + echo "File not found: $file" + fi } # Read the style file with unused keys @@ -109,24 +107,39 @@ lookfor_unused_keywords() { # Function to find and store keys from a file -find_styles_and_store_keys() { +find_styles_object_and_store_keys() { local file="$1" local base_name="${2:-styles}" # Set styles as default local parent_keys=() local root_key="" local line_number=0 + local inside_arrow_function=false while IFS= read -r line; do ((line_number++)) + # Check if we are inside an arrow function and we find a closing curly brace + if [[ "$inside_arrow_function" == true ]]; then + if [[ "$line" =~ ^[[:space:]]*\}\) ]]; then + inside_arrow_function=false + fi + continue + fi + + # Check if we are inside an arrow function + if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then + inside_arrow_function=true + continue + fi + # Skip lines that are not key-related - if [[ ! "$line" =~ $OBJ_PROP_DECLARATION_REGEX && ! "$line" =~ $CAPTURE_ARROW_FUNC_REGEX ]]; then + if [[ ! "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\} ]]; then continue fi - if [[ "$line" =~ $OBJ_DEFINITION_REGEX ]]; then + if [[ "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{ ]]; then root_key="${BASH_REMATCH[2]%%:*{*)}" - elif [[ "$line" =~ $CAPTURE_OBJ_ARROW_FUNC_REGEX ]]; then + elif [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then # Removing all the extra lines after the ":" local key="${line%%:*}" key="${key// /}" # Trim spaces @@ -150,6 +163,42 @@ find_styles_and_store_keys() { done < "$file" } +find_styles_functions_and_store_keys() { + local file="$1" + local line_number=0 + local inside_object=false + local inside_arrow_function=false + local key="" + + while IFS= read -r line; do + ((line_number++)) + + # Check if we are inside an arrow function + if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then + inside_arrow_function=true + key="${line%%:*}" + key="${key// /}" # Trim spaces + echo "styles.${key}:${file}:${line_number}" >> "$STYLES_KEYS_FILE" + fi + + # If we are inside an arrow function and we find an opening curly brace, + # then set inside_object to true, indicating we are inside an object. + if [[ "$inside_arrow_function" == true && "$line" =~ ^[[:space:]]*\{ ]]; then + inside_object=true + fi + + # If we are inside an object, continue to the next line. + if [[ "$inside_object" == true ]]; then + continue + fi + + # If we find a closing curly brace, reset the inside_object flag. + if [[ "$line" =~ ^[[:space:]]*\},?$ ]]; then + inside_object=false + fi + done < "$file" +} + find_utility_styles_store_prefix() { # Loop through all files in the src folder while read -r file; do @@ -179,7 +228,7 @@ find_utility_usage_as_styles() { continue fi - find_styles_and_store_keys "${file}" "${root_key}" + find_styles_object_and_store_keys "${file}" "${root_key}" done < <(find "${UTILITIES_STYLES_FILE}" -type f \( "${FILE_EXTENSIONS[@]}" \)) } @@ -203,19 +252,19 @@ lookfor_unused_utilities() { done < "$UTILITY_STYLES_KEYS_FILE" } +echo "🔍 Looking for styles." # Find and store the name of the utility files as keys find_utility_styles_store_prefix +find_utility_usage_as_styles # Find and store keys from styles.js -find_styles_and_store_keys "$STYLES_FILE" +find_styles_object_and_store_keys "$STYLES_FILE" +find_styles_functions_and_store_keys "$STYLES_FILE" -find_utility_usage_as_styles +echo "🗄️ Now going through the codebase and looking for unused keys." # Look for usages of utilities into src/styles lookfor_unused_utilities - -echo "⏱️ Now going through the list and looking for unused keys." - lookfor_unused_keywords final_styles_line_count=$(count_lines "$STYLES_KEYS_FILE") diff --git a/src/styles/styles.js b/src/styles/styles.js index 1c1340600a51..2fd346bed64c 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -174,12 +174,6 @@ const styles = { ...themeColors, ...textUnderline, - rateCol: { - margin: 0, - padding: 0, - flexBasis: '48%', - }, - autoCompleteSuggestionsContainer: { backgroundColor: themeColors.appBG, borderRadius: 8, @@ -236,13 +230,6 @@ const styles = { borderRadius: 12, }, - unitCol: { - margin: 0, - padding: 0, - marginLeft: '4%', - flexBasis: '48%', - }, - webViewStyles, link, @@ -265,19 +252,6 @@ const styles = { backgroundColor: themeColors.appBG, }, - h1: { - color: themeColors.heading, - fontFamily: fontFamily.EXP_NEUE_BOLD, - fontSize: variables.fontSizeh1, - fontWeight: fontWeightBold, - }, - - h3: { - fontFamily: fontFamily.EXP_NEUE_BOLD, - fontSize: variables.fontSizeNormal, - fontWeight: fontWeightBold, - }, - h4: { fontFamily: fontFamily.EXP_NEUE_BOLD, fontSize: variables.fontSizeLabel, @@ -428,10 +402,6 @@ const styles = { color: themeColors.textSupporting, }, - colorHeading: { - color: themeColors.heading, - }, - bgTransparent: { backgroundColor: 'transparent', }, @@ -632,10 +602,6 @@ const styles = { backgroundColor: themeColors.activeComponentBG, }, - fontWeightBold: { - fontWeight: fontWeightBold, - }, - touchableButtonImage: { alignItems: 'center', height: variables.componentSizeNormal, @@ -829,10 +795,6 @@ const styles = { height: CONST.DESKTOP_HEADER_PADDING, }, - pushTextRight: { - left: 100000, - }, - reportOptions: { marginLeft: 8, }, @@ -1104,10 +1066,6 @@ const styles = { noOutline: addOutlineWidth({}, 0), - errorOutline: { - borderColor: themeColors.danger, - }, - textLabelSupporting: { fontFamily: fontFamily.EXP_NEUE, fontSize: variables.fontSizeLabel, @@ -1173,13 +1131,6 @@ const styles = { marginBottom: 4, }, - desktopRedirectPage: { - backgroundColor: themeColors.appBG, - minHeight: '100%', - flex: 1, - alignItems: 'center', - }, - signInPage: { backgroundColor: themeColors.highlightBG, minHeight: '100%', @@ -1559,11 +1510,6 @@ const styles = { width: 18, }, - chatContent: { - flex: 4, - justifyContent: 'flex-end', - }, - chatContentScrollView: { flexGrow: 1, justifyContent: 'flex-start', @@ -1718,11 +1664,6 @@ const styles = { textAlignVertical: 'top', }, - editInputComposeSpacing: { - backgroundColor: themeColors.transparent, - marginVertical: 8, - }, - // composer padding should not be modified unless thoroughly tested against the cases in this PR: #12669 textInputComposeSpacing: { paddingVertical: 5, @@ -1844,23 +1785,6 @@ const styles = { width: 200, }, - chatSwticherPillWrapper: { - marginTop: 5, - marginRight: 4, - }, - - navigationModalOverlay: { - ...userSelect.userSelectNone, - position: 'absolute', - width: '100%', - height: '100%', - transform: [ - { - translateX: -variables.sideBarWidth, - }, - ], - }, - sidebarVisible: { borderRightWidth: 1, }, @@ -1885,14 +1809,6 @@ const styles = { borderRadius: 24, }, - singleSubscript: { - height: variables.iconSizeNormal, - width: variables.iconSizeNormal, - backgroundColor: themeColors.icon, - borderRadius: 20, - zIndex: 1, - }, - singleAvatarSmall: { height: 18, width: 18, @@ -1936,17 +1852,6 @@ const styles = { right: 0, }, - leftSideLargeAvatar: { - left: 15, - }, - - rightSideLargeAvatar: { - right: 15, - zIndex: 2, - borderWidth: 4, - borderRadius: 100, - }, - secondAvatarInline: { bottom: -3, right: -25, @@ -1961,18 +1866,6 @@ const styles = { height: variables.avatarSizeLarge, }, - avatarNormal: { - height: variables.componentSizeNormal, - width: variables.componentSizeNormal, - borderRadius: variables.componentSizeNormal, - }, - - avatarSmall: { - height: variables.avatarSizeSmall, - width: variables.avatarSizeSmall, - borderRadius: variables.avatarSizeSmall, - }, - avatarInnerText: { color: themeColors.textLight, fontSize: variables.fontSizeSmall, @@ -1989,21 +1882,6 @@ const styles = { textAlign: 'center', }, - avatarSpace: { - top: 3, - left: 3, - }, - - avatar: { - backgroundColor: themeColors.sidebar, - borderColor: themeColors.sidebar, - }, - - focusedAvatar: { - backgroundColor: themeColors.border, - borderColor: themeColors.border, - }, - emptyAvatar: { height: variables.avatarSizeNormal, width: variables.avatarSizeNormal, @@ -2050,11 +1928,6 @@ const styles = { marginRight: variables.avatarChatSpacing - 4, }, - modalViewContainer: { - alignItems: 'center', - flex: 1, - }, - borderTop: { borderTopWidth: variables.borderTopWidth, borderColor: themeColors.border, @@ -2144,14 +2017,6 @@ const styles = { ...(isSmallScreenWidth && flex.flex1), }), - modalCenterContentContainer: { - flex: 1, - flexDirection: 'column', - justifyContent: 'center', - alignItems: 'center', - backgroundColor: themeColors.modalBackdrop, - }, - centeredModalStyles: (isSmallScreenWidth, isFullScreenWhenSmall) => ({ borderWidth: isSmallScreenWidth && !isFullScreenWhenSmall ? 1 : 0, marginHorizontal: isSmallScreenWidth ? 0 : 20, @@ -2174,28 +2039,6 @@ const styles = { alignItems: 'center', }, - notFoundSafeArea: { - flex: 1, - backgroundColor: themeColors.heading, - }, - - notFoundView: { - flex: 1, - alignItems: 'center', - paddingTop: 40, - paddingBottom: 40, - justifyContent: 'space-between', - }, - - notFoundLogo: { - width: 202, - height: 63, - }, - - notFoundContent: { - alignItems: 'center', - }, - notFoundTextHeader: { ...headlineFont, color: themeColors.heading, @@ -2206,20 +2049,6 @@ const styles = { textAlign: 'center', }, - notFoundTextBody: { - color: themeColors.componentBG, - fontFamily: fontFamily.EXP_NEUE_BOLD, - fontWeight: fontWeightBold, - fontSize: 15, - }, - - notFoundButtonText: { - color: themeColors.link, - fontFamily: fontFamily.EXP_NEUE_BOLD, - fontWeight: fontWeightBold, - fontSize: 15, - }, - blockingViewContainer: { paddingBottom: variables.contentHeaderHeight, }, @@ -2270,18 +2099,6 @@ const styles = { justifyContent: 'space-around', }, - settingsPageColumn: { - width: '100%', - alignItems: 'center', - justifyContent: 'space-around', - }, - - settingsPageContainer: { - justifyContent: 'space-between', - alignItems: 'center', - width: '100%', - }, - twoFactorAuthSection: { backgroundColor: themeColors.appBG, padding: 0, @@ -2419,18 +2236,6 @@ const styles = { left: -16, }, - svgAvatarBorder: { - borderRadius: 100, - overflow: 'hidden', - }, - - displayName: { - fontSize: variables.fontSizeLarge, - fontFamily: fontFamily.EXP_NEUE_BOLD, - fontWeight: fontWeightBold, - color: themeColors.heading, - }, - pageWrapper: { width: '100%', alignItems: 'center', @@ -2502,21 +2307,11 @@ const styles = { transform: [{rotate: '180deg'}], }, - navigationSceneContainer: { - backgroundColor: themeColors.appBG, - }, - navigationScreenCardStyle: { backgroundColor: themeColors.appBG, height: '100%', }, - navigationSceneFullScreenWrapper: { - borderRadius: variables.componentBorderRadiusCard, - overflow: 'hidden', - height: '100%', - }, - invisible: { position: 'absolute', opacity: 0, @@ -2554,14 +2349,6 @@ const styles = { paddingBottom: 0, }, - detailsPageSectionVersion: { - alignSelf: 'center', - color: themeColors.textSupporting, - fontSize: variables.fontSizeSmall, - height: 24, - lineHeight: 20, - }, - switchTrack: { width: 50, height: 28, @@ -2711,12 +2498,6 @@ const styles = { alignSelf: 'center', }, - iouDetailsContainer: { - flexGrow: 1, - paddingStart: 20, - paddingEnd: 20, - }, - codeWordWrapper: { ...codeStyles.codeWordWrapper, }, @@ -2756,11 +2537,6 @@ const styles = { zIndex: 10, }, - navigatorFullScreenLoading: { - backgroundColor: themeColors.highlightBG, - opacity: 1, - }, - reimbursementAccountFullScreenLoading: { backgroundColor: themeColors.componentBG, opacity: 0.8, @@ -2845,40 +2621,6 @@ const styles = { height: '100%', }, - fullscreenCard: { - position: 'absolute', - left: 0, - top: 0, - width: '100%', - height: '100%', - }, - - fullscreenCardWeb: { - left: 'auto', - right: '-24%', - top: '-18%', - height: '120%', - }, - - fullscreenCardWebCentered: { - left: '0', - right: '0', - top: '0', - height: '60%', - }, - - fullscreenCardMobile: { - left: '-20%', - top: '-30%', - width: '150%', - }, - - fullscreenCardMediumScreen: { - left: '-15%', - top: '-30%', - width: '145%', - }, - smallEditIcon: { alignItems: 'center', backgroundColor: themeColors.buttonHoveredBG, @@ -2897,41 +2639,6 @@ const styles = { bottom: -4, }, - workspaceCard: { - width: '100%', - height: 400, - borderRadius: variables.componentBorderRadiusCard, - overflow: 'hidden', - backgroundColor: themeColors.heroCard, - }, - - workspaceCardMobile: { - height: 475, - }, - - workspaceCardMediumScreen: { - height: 540, - }, - - workspaceCardMainText: { - fontSize: variables.fontSizeXXXLarge, - fontWeight: 'bold', - lineHeight: variables.fontSizeXXXLarge, - }, - - workspaceCardContent: { - zIndex: 1, - padding: 50, - }, - - workspaceCardContentMediumScreen: { - padding: 25, - }, - - workspaceCardCTA: { - width: 250, - }, - autoGrowHeightMultilineInput: { maxHeight: 115, }, @@ -3011,12 +2718,6 @@ const styles = { opacity: variables.overlayOpacity, }, - communicationsLinkIcon: { - right: -36, - top: 0, - bottom: 0, - }, - shortTermsBorder: { borderWidth: 1, borderColor: themeColors.border, @@ -3202,10 +2903,6 @@ const styles = { fontSize: 48, }, - closeAccountMessageInput: { - height: 153, - }, - imageCropContainer: { overflow: 'hidden', alignItems: 'center', @@ -3302,24 +2999,11 @@ const styles = { alignItems: 'center', }, - callRequestSection: { - backgroundColor: themeColors.appBG, - paddingHorizontal: 0, - paddingBottom: 0, - marginHorizontal: 0, - marginBottom: 0, - }, - archivedReportFooter: { borderRadius: variables.componentBorderRadius, ...wordBreak.breakWord, }, - saveButtonPadding: { - paddingLeft: 18, - paddingRight: 18, - }, - deeplinkWrapperContainer: { padding: 20, flex: 1, @@ -3365,11 +3049,7 @@ const styles = { alignSelf: 'flex-start', marginRight: 4, }, - reactionListItem: { - flexDirection: 'row', - paddingVertical: 12, - paddingHorizontal: 20, - }, + reactionListHeaderText: { color: themeColors.textSupporting, marginLeft: 8, @@ -3461,11 +3141,6 @@ const styles = { width: '100%', }, - listPickerSeparator: { - height: 1, - backgroundColor: themeColors.buttonDefaultBG, - }, - datePickerRoot: { position: 'relative', zIndex: 99, @@ -3518,15 +3193,6 @@ const styles = { width: 16, }, - validateCodeMessage: { - width: variables.modalContentMaxWidth, - textAlign: 'center', - }, - - whisper: { - backgroundColor: themeColors.cardBG, - }, - contextMenuItemPopoverMaxWidth: { maxWidth: 375, }, From 6756074fa9163d0367e8e60d4cc21c2dbc73eff2 Mon Sep 17 00:00:00 2001 From: Eduardo Date: Mon, 18 Sep 2023 13:18:39 +0200 Subject: [PATCH 17/19] Updated script to handle styles with theme function, and obj spreading in style.js file --- .github/scripts/findUnusedKeys.sh | 154 ++++++++++++++++++++++++------ 1 file changed, 123 insertions(+), 31 deletions(-) diff --git a/.github/scripts/findUnusedKeys.sh b/.github/scripts/findUnusedKeys.sh index 85d8112e8f13..e34d8e0d78ea 100755 --- a/.github/scripts/findUnusedKeys.sh +++ b/.github/scripts/findUnusedKeys.sh @@ -110,6 +110,85 @@ lookfor_unused_keywords() { find_styles_object_and_store_keys() { local file="$1" local base_name="${2:-styles}" # Set styles as default + local line_number=0 + local inside_arrow_function=false + + while IFS= read -r line; do + ((line_number++)) + + # Check if we are inside an arrow function and we find a closing curly brace + if [[ "$inside_arrow_function" == true ]]; then + if [[ "$line" =~ ^[[:space:]]*\}\) ]]; then + inside_arrow_function=false + fi + continue + fi + + # Check if we are inside an arrow function + if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ || "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\(.*\)[[:space:]]*'=>' ]]; then + inside_arrow_function=true + continue + fi + + # Skip lines that are not key-related + if [[ ! "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\} ]]; then + continue + fi + + if [[ "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{ ]]; then + key="${BASH_REMATCH[2]%%:*{*)}" + echo "styles.${key}|...${key}|${base_name}.${key}:${file}:${line_number}" >> "$STYLES_KEYS_FILE" + fi + done < "$file" +} + +find_styles_functions_and_store_keys() { + local file="$1" + local line_number=0 + local inside_object=false + local inside_arrow_function=false + local key="" + + while IFS= read -r line; do + ((line_number++)) + + # Skip lines that are not key-related + if [[ "${line}" == *styles* ]]; then + continue + fi + + # Check if we are inside an arrow function and we find a closing curly brace + if [[ "$inside_arrow_function" == true ]]; then + if [[ "$line" =~ ^[[:space:]]*\}\) ]]; then + inside_arrow_function=false + fi + continue + fi + + # Check if we are inside an arrow function + if [[ "${line}" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\( ]]; then + inside_arrow_function=true + key="${line%%:*}" + key="${key// /}" # Trim spaces + echo "styles.${key}|...${key}:${file}:${line_number}" >> "$STYLES_KEYS_FILE" + continue + fi + + if [[ "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\(.*\)[[:space:]]*'=>' ]]; then + inside_arrow_function=true + key="${BASH_REMATCH[2]}" + key="${key// /}" # Trim spaces + echo "styles.${key}|...${key}:${file}:${line_number}" >> "$STYLES_KEYS_FILE" + continue + fi + + done < "$file" +} + +find_theme_style_and_store_keys() { + local file="$1" + local start_line_number="$2" + local base_name="${3:-styles}" # Set styles as default local parent_keys=() local root_key="" local line_number=0 @@ -118,6 +197,10 @@ find_styles_object_and_store_keys() { while IFS= read -r line; do ((line_number++)) + if [ ! "$line_number" -ge "$start_line_number" ]; then + continue + fi + # Check if we are inside an arrow function and we find a closing curly brace if [[ "$inside_arrow_function" == true ]]; then if [[ "$line" =~ ^[[:space:]]*\}\) ]]; then @@ -127,22 +210,22 @@ find_styles_object_and_store_keys() { fi # Check if we are inside an arrow function - if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then + if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ || "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\(.*\)[[:space:]]*'=>' ]]; then inside_arrow_function=true continue fi # Skip lines that are not key-related if [[ ! "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*\} ]]; then + continue fi - if [[ "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\{ ]]; then - root_key="${BASH_REMATCH[2]%%:*{*)}" - elif [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then + if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{|^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then # Removing all the extra lines after the ":" local key="${line%%:*}" key="${key// /}" # Trim spaces + if [[ ${#parent_keys[@]} -gt 0 ]]; then local parent_key_trimmed="${parent_keys[${#parent_keys[@]}-1]// /}" # Trim spaces key="$parent_key_trimmed.$key" @@ -150,12 +233,8 @@ find_styles_object_and_store_keys() { local parent_key_trimmed="${root_key// /}" # Trim spaces key="$parent_key_trimmed.$key" fi - - if [[ "$key" == "styles."* ]]; then - echo "${key}:${file}:${line_number}" >> "$STYLES_KEYS_FILE" - else - echo "styles.${key}|${base_name}.${key}:${file}:${line_number}" >> "$STYLES_KEYS_FILE" - fi + + echo "styles.${key}|...${key}|${base_name}.${key}:${file}:${line_number}" >> "$STYLES_KEYS_FILE" parent_keys+=("$key") elif [[ "$line" =~ ^[[:space:]]*\} ]]; then parent_keys=("${parent_keys[@]:0:${#parent_keys[@]}-1}") @@ -163,40 +242,51 @@ find_styles_object_and_store_keys() { done < "$file" } -find_styles_functions_and_store_keys() { +# Given that all the styles are inside of a function, we need to find the function and then look for the styles +collect_theme_keys_from_styles() { local file="$1" local line_number=0 - local inside_object=false - local inside_arrow_function=false - local key="" + local inside_styles=false while IFS= read -r line; do ((line_number++)) - # Check if we are inside an arrow function - if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-])+:[[:space:]]*\(.*\)[[:space:]]*'=>'[[:space:]]*\(\{ ]]; then - inside_arrow_function=true - key="${line%%:*}" - key="${key// /}" # Trim spaces - echo "styles.${key}:${file}:${line_number}" >> "$STYLES_KEYS_FILE" + if [[ "$inside_styles" == false ]]; then + if [[ "$line" =~ ^[[:space:]]*(const|let|var)[[:space:]]+([a-zA-Z0-9_-]+)[[:space:]]*=[[:space:]]*\(.*\)[[:space:]]*'=>' ]]; then + key="${BASH_REMATCH[2]}" + key="${key// /}" # Trim spaces + if [[ "$key" == "styles"* ]]; then + inside_styles=true + # Need to start within the style function + ((line_number++)) + find_theme_style_and_store_keys "$file" "$line_number" + fi + continue + fi fi + done < "$file" +} - # If we are inside an arrow function and we find an opening curly brace, - # then set inside_object to true, indicating we are inside an object. - if [[ "$inside_arrow_function" == true && "$line" =~ ^[[:space:]]*\{ ]]; then - inside_object=true - fi +lookfor_unused_spread_keywords() { + local inside_object=false - # If we are inside an object, continue to the next line. - if [[ "$inside_object" == true ]]; then - continue + while IFS= read -r line; do + # Detect the start of an object + if [[ "$line" =~ ^[[:space:]]*([a-zA-Z0-9_-]+\.)?[a-zA-Z0-9_-]+:[[:space:]]*\{ ]]; then + inside_object=true fi - # If we find a closing curly brace, reset the inside_object flag. + # Detect the end of an object if [[ "$line" =~ ^[[:space:]]*\},?$ ]]; then inside_object=false fi - done < "$file" + + # If we're inside an object and the line starts with '...', capture the key + if [[ "$inside_object" == true && "$line" =~ ^[[:space:]]*\.\.\.([a-zA-Z0-9_]+)(\(.+\))?,?$ ]]; then + local key=("${BASH_REMATCH[1]}") + remove_keyword "...${key}" + fi + done < "$STYLES_FILE" } find_utility_styles_store_prefix() { @@ -228,7 +318,7 @@ find_utility_usage_as_styles() { continue fi - find_styles_object_and_store_keys "${file}" "${root_key}" + find_theme_style_and_store_keys "${file}" 0 "${root_key}" done < <(find "${UTILITIES_STYLES_FILE}" -type f \( "${FILE_EXTENSIONS[@]}" \)) } @@ -260,11 +350,13 @@ find_utility_usage_as_styles # Find and store keys from styles.js find_styles_object_and_store_keys "$STYLES_FILE" find_styles_functions_and_store_keys "$STYLES_FILE" +collect_theme_keys_from_styles "$STYLES_FILE" echo "🗄️ Now going through the codebase and looking for unused keys." # Look for usages of utilities into src/styles lookfor_unused_utilities +lookfor_unused_spread_keywords lookfor_unused_keywords final_styles_line_count=$(count_lines "$STYLES_KEYS_FILE") From 54e786c1593e5a53ba9c58827c345908be6420af Mon Sep 17 00:00:00 2001 From: Eduardo Date: Mon, 18 Sep 2023 13:36:08 +0200 Subject: [PATCH 18/19] fixed some lint issues --- .github/scripts/findUnusedKeys.sh | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/scripts/findUnusedKeys.sh b/.github/scripts/findUnusedKeys.sh index e34d8e0d78ea..6668d3257546 100755 --- a/.github/scripts/findUnusedKeys.sh +++ b/.github/scripts/findUnusedKeys.sh @@ -259,7 +259,7 @@ collect_theme_keys_from_styles() { inside_styles=true # Need to start within the style function ((line_number++)) - find_theme_style_and_store_keys "$file" "$line_number" + find_theme_style_and_store_keys "$STYLES_FILE" "$line_number" fi continue fi @@ -269,6 +269,7 @@ collect_theme_keys_from_styles() { lookfor_unused_spread_keywords() { local inside_object=false + local key="" while IFS= read -r line; do # Detect the start of an object @@ -283,7 +284,7 @@ lookfor_unused_spread_keywords() { # If we're inside an object and the line starts with '...', capture the key if [[ "$inside_object" == true && "$line" =~ ^[[:space:]]*\.\.\.([a-zA-Z0-9_]+)(\(.+\))?,?$ ]]; then - local key=("${BASH_REMATCH[1]}") + key="${BASH_REMATCH[1]}" remove_keyword "...${key}" fi done < "$STYLES_FILE" From 24e4db5626db5a0e29238565240fa7f5de913e1d Mon Sep 17 00:00:00 2001 From: Eduardo Date: Mon, 18 Sep 2023 16:03:35 +0200 Subject: [PATCH 19/19] removed unused style --- src/styles/styles.js | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/styles/styles.js b/src/styles/styles.js index a8b764dc0e39..81f3c22c0dae 100644 --- a/src/styles/styles.js +++ b/src/styles/styles.js @@ -225,11 +225,6 @@ const styles = (theme) => ({ color: theme.textSupporting, }, - appIconBorderRadius: { - overflow: 'hidden', - borderRadius: 12, - }, - webViewStyles: webViewStyles(theme), link: link(theme),