Last active
June 17, 2025 03:04
-
-
Save MedRedha/eb8b8d4b1c4d7492e09d04360adc5812 to your computer and use it in GitHub Desktop.
Pulse - Checking the vital signs of your developer toolchain
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/bash | |
# ____ ___ | |
# /\ _`\ /\_ \ | |
# \ \ \L\ \ __ __\//\ \ ____ __ | |
# \ \ ,__//\ \/\ \ \ \ \ /',__\ /'__`\ | |
# \ \ \/ \ \ \_\ \ \_\ \_ /\__, `\/\ __/ | |
# \ \_\ \ \____/ /\____\/\____/\ \____\ | |
# \/_/ \/___/ \/____/ \/___/ \/____/ | |
# | |
# Checking the vital signs of your developer toolchain. | |
# | |
# by Med Redha Khelifi (@MedRedha) | |
# | |
GREEN='\033[0;32m' | |
RED='\033[0;31m' | |
YELLOW='\033[1;33m' | |
ORANGE='\033[38;5;202m' | |
CYAN='\033[0;36m' | |
GRAY='\033[0;90m' | |
NC='\033[0m' | |
ERASE_LINE='\033[K' | |
updates_available=0 | |
tools_ok=0 | |
source_nvm() { | |
export NVM_DIR="$HOME/.nvm" | |
if [ -s "$NVM_DIR/nvm.sh" ]; then | |
# shellcheck disable=SC1091 | |
source "$NVM_DIR/nvm.sh" | |
fi | |
} | |
is_latest_newer() { | |
local current_ver=$1 | |
local latest_ver=$2 | |
current_ver=${current_ver#\~} | |
current_ver=${current_ver#\^} | |
[ -z "$current_ver" ] && current_ver="0" | |
[ -z "$latest_ver" ] && latest_ver="0" | |
current_ver=${current_ver#v} | |
latest_ver=${latest_ver#v} | |
if [ "$current_ver" == "$latest_ver" ]; then return 1; fi | |
if [ "$(printf '%s\n' "$current_ver" "$latest_ver" | sort -V | tail -n1)" == "$latest_ver" ]; then | |
return 0 | |
else | |
return 1 | |
fi | |
} | |
process_check() { | |
local icon="$1" | |
local tool_name="$2" | |
local current_ver="$3" | |
local latest_ver="$4" | |
local update_cmd="$5" | |
local display_ver="$current_ver" | |
if [ -z "$current_ver" ]; then | |
display_ver="not installed" | |
fi | |
echo -e "---------------------------------" | |
if is_latest_newer "$current_ver" "$latest_ver"; then | |
((updates_available++)) | |
echo -e "${RED} ${icon} ${tool_name} ${NC}needs an update!" | |
echo -e " ├─ Installed: ${YELLOW}${display_ver}${NC}" | |
echo -e " ├─ Latest: ${GREEN}${latest_ver}${NC}" | |
echo -e " └─ Action: ${CYAN}${update_cmd}${NC}" | |
else | |
((tools_ok++)) | |
echo -e "${GREEN}✔ ${icon} ${tool_name} ${NC}is up-to-date ${CYAN}(${display_ver})${NC}" | |
fi | |
} | |
display_tool_version() { | |
local icon="$1" | |
local tool_name="$2" | |
local current_ver="$3" | |
echo -e "---------------------------------" | |
if [ -z "$current_ver" ] || [[ "$current_ver" == *"No such file or directory"* ]]; then | |
current_ver="not found" | |
fi | |
echo -e "${GREEN}✔ ${icon} ${tool_name}${NC}: ${CYAN}${current_ver}${NC}" | |
} | |
display_logo() { | |
local title | |
title=$(figlet -c -k -f larry3d "Pulse" | sed '/^ *$/d') | |
local subtitle | |
subtitle=$(figlet -c -f term "Checking the vital signs of your developer toolchain." | sed '/^ *$/d') | |
local credit | |
credit=$(figlet -c -f term "by Med Redha Khelifi (@MedRedha)" | sed '/^ *$/d') | |
echo -e "${ORANGE}${title}${NC}" | |
echo "" | |
echo -e "${CYAN}${subtitle}${NC}" | |
echo "" | |
echo -e "${GRAY}${credit}${NC}" | |
echo "" | |
} | |
main() { | |
display_logo | |
source_nvm | |
spinner='⠋⠙⠹⠸⠼⠴⠦⠧⠇⠏' | |
spinner_idx=0 | |
read -r -d '' CHECKS << EOF | |
check;;Node;node -v | sed 's/v//';npm view node version;nvm install node && nvm alias default node | |
check;;NVM;nvm --version;curl -s "https://api.github.com/repos/nvm-sh/nvm/releases/latest" | jq -r .tag_name | sed 's/v//';curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/\$(curl -s "https://api.github.com/repos/nvm-sh/nvm/releases/latest" | jq -r .tag_name)/install.sh | bash | |
check;;Yarn;yarn -v;npm view yarn version;corepack prepare yarn@stable --activate | |
check;;Prettier;prettier -v;npm view prettier version;npm install -g prettier | |
check;;Firebase CLI;firebase --version;npm view firebase-tools version;npm install -g firebase-tools | |
check;;Ruby;ruby -v | awk '{print \$2}' | cut -d'p' -f1;brew info --json ruby | jq -r '.[0].versions.stable';brew upgrade ruby | |
check;;RubyGems;gem -v;curl -s https://rubygems.org/api/v1/gems/rubygems-update.json | jq -r .version;gem update --system | |
check;;Bundler;bundle -v | awk '{print \$3}';curl -s https://rubygems.org/api/v1/gems/bundler.json | jq -r .version;gem install bundler && bundle update --bundler | |
check;;Cocoapods;pod --version;curl -s https://rubygems.org/api/v1/gems/cocoapods.json | jq -r .version;gem install cocoapods | |
check;;Homebrew;brew --version | head -n 1 | awk '{print \$2}';curl -s "https://api.github.com/repos/Homebrew/brew/releases/latest" | jq -r .tag_name;brew update | |
check;;Watchman;watchman -v;brew info --json watchman | jq -r '.[0].versions.stable';brew upgrade watchman | |
check;;Java;java -version 2>&1 | grep -i version | awk -F'"' '{print \$2}';brew info --json openjdk | jq -r '.[0].versions.stable';brew upgrade openjdk | |
check;;JQ;jq --version | cut -d- -f2;brew info --json jq | jq -r '.[0].versions.stable';brew upgrade jq | |
--- | |
display;;Xcode;xcrun xctrace version 2>/dev/null | head -n 1 | |
display;;Android SDK;ls \${ANDROID_HOME:-\$HOME/Library/Android/sdk}/build-tools 2>/dev/null | tail -n 1 | |
display;;Android NDK;ls \${ANDROID_HOME:-\$HOME/Library/Android/sdk}/ndk 2>/dev/null | tail -n 1 | |
EOF | |
while IFS=';' read -r type icon name current_cmd latest_cmd update_cmd; do | |
spinner_char=${spinner:$spinner_idx:1} | |
spinner_idx=$(( (spinner_idx+1) % ${#spinner} )) | |
printf "\r${ERASE_LINE}${ORANGE}${spinner_char} Checking ${name}...${NC}" | |
current_ver=$(eval "$current_cmd") | |
latest_ver=$(eval "$latest_cmd") | |
printf "\r${ERASE_LINE}" | |
process_check "$icon" "$name" "$current_ver" "$latest_ver" "$update_cmd" | |
done <<< "$(echo "$CHECKS" | grep '^check')" | |
if [ -f "package.json" ]; then | |
spinner_char=${spinner:$spinner_idx:1} | |
spinner_idx=$(( (spinner_idx+1) % ${#spinner} )) | |
printf "\r${ERASE_LINE}${CYAN}${spinner_char} Checking React Native CLI...${NC}" | |
current_ver=$(jq -r '.devDependencies["@react-native-community/cli"] // ""' package.json) | |
latest_ver=$(npm view @react-native-community/cli version) | |
printf "\r${ERASE_LINE}" | |
if [ -n "$current_ver" ]; then | |
process_check "" "React Native CLI" "$current_ver" "$latest_ver" "yarn add -D @react-native-community/cli@latest" | |
fi | |
spinner_char=${spinner:$spinner_idx:1} | |
spinner_idx=$(( (spinner_idx+1) % ${#spinner} )) | |
printf "\r${ERASE_LINE}${CYAN}${spinner_char} Checking React Native Lib...${NC}" | |
current_ver=$(jq -r '.dependencies["react-native"] // ""' package.json) | |
latest_ver=$(npm view react-native version) | |
printf "\r${ERASE_LINE}" | |
if [ -n "$current_ver" ]; then | |
process_check "" "React Native" "$current_ver" "$latest_ver" "yarn add react-native@latest" | |
fi | |
fi | |
while IFS=';' read -r type icon name current_cmd; do | |
spinner_char=${spinner:$spinner_idx:1} | |
spinner_idx=$(( (spinner_idx+1) % ${#spinner} )) | |
printf "\r${ERASE_LINE}${CYAN}${spinner_char} Checking ${name}...${NC}" | |
current_ver=$(eval "$current_cmd") | |
printf "\r${ERASE_LINE}" | |
display_tool_version "$icon" "$name" "$current_ver" | |
done <<< "$(echo "$CHECKS" | grep '^display')" | |
echo "---------------------------------" | |
echo -e "${CYAN} Pulse Check Complete${NC}" | |
echo -e " ${GREEN} ${tools_ok} tools are up-to-date.${NC}" | |
if [ "$updates_available" -gt 0 ]; then | |
echo -e " ${RED} ${updates_available} update(s) available.${NC}" | |
fi | |
echo "" | |
} | |
main |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment