@@ -37,13 +37,117 @@ animate_border() {
3737 echo
3838}
3939
40+ # Helper function to count emojis in text
41+ count_emojis () {
42+ local text=" $1 "
43+ local count=0
44+
45+ # List of emojis used in this script (each should be counted)
46+ # Note: Some emojis like π₯οΈ and β±οΈ include variation selectors which are handled separately
47+ local emojis=" π³ π
β° π€ π₯ π π§ πΎ β‘ β± π π π‘ π π¦ π§ π π π₯ π― π π π¨ β πΏ β π πͺ π π β π π π π π’ π π
β π β"
48+
49+ # Count each emoji type (without variation selectors in the search pattern)
50+ for emoji in $emojis ; do
51+ local found=$( echo " $text " | grep -o " $emoji " 2> /dev/null | wc -l)
52+ count=$(( count + found))
53+ done
54+
55+ echo " $count "
56+ }
57+
58+ # Helper function to count variation selectors (zero-width characters that add to string length but not display)
59+ count_variation_selectors () {
60+ local text=" $1 "
61+ # Variation Selector-16 (U+FE0F) appears after some emojis like π₯οΈ and β±οΈ
62+ # These are counted by bash as characters but display as zero width
63+ # We need to subtract them from the length since they don't display
64+ local vs_count=$( echo " $text " | grep -o $' \uFE0F' 2> /dev/null | wc -l)
65+ echo " $vs_count "
66+ }
67+
68+ # Standard boxing function - creates a box around content
69+ # Usage: draw_box <border_color> <title> <box_width> [line1] [line2] ...
70+ draw_box () {
71+ local border_color=" $1 "
72+ local title=" $2 "
73+ local box_width=" $3 "
74+ shift 3
75+ local lines=(" $@ " )
76+
77+ # Calculate internal width (box_width minus borders and padding: "β " + " β")
78+ local internal_width=$(( box_width - 4 ))
79+
80+ # Top border
81+ echo -e " ${border_color} β$( printf ' β%.0s' $( seq 1 $(( box_width - 2 )) ) ) β${NC} "
82+
83+ # Title (if provided)
84+ if [ -n " $title " ]; then
85+ # Strip colors and measure
86+ local title_clean=$( echo -e " $title " | sed ' s/\x1b\[[0-9;]*m//g' )
87+ # Count actual character positions (bash's ${#var} counts multi-byte chars correctly)
88+ local title_len=${# title_clean}
89+ # Count emojis (each takes 2 display columns but bash counts as 1)
90+ local title_emoji_count=$( count_emojis " $title_clean " )
91+ # Count variation selectors (counted as 1 char by bash but 0 width display)
92+ local title_vs_count=$( count_variation_selectors " $title_clean " )
93+ # Display width: emojis with VS are already counted as 2 by bash and display as 2
94+ # So: display = bash_length + (emojis without VS) - (VS count * 2, since they add to bash count but not display and block the emoji +1)
95+ local display_adjustment=$(( title_emoji_count - title_vs_count - title_vs_count))
96+ local title_display=$(( title_len + display_adjustment))
97+
98+ local title_padding=$(( (internal_width - title_display) / 2 ))
99+ local title_padding_right=$(( internal_width - title_display - title_padding ))
100+ printf " ${border_color} β${NC} "
101+ printf " %*s" $title_padding " "
102+ echo -ne " $title "
103+ printf " %*s" $title_padding_right " "
104+ echo -e " ${border_color} β${NC} "
105+ echo -e " ${border_color} β $( printf ' β%.0s' $( seq 1 $(( box_width - 2 )) ) ) β£${NC} "
106+ fi
107+
108+ # Content lines
109+ for line in " ${lines[@]} " ; do
110+ # Strip ANSI codes
111+ local line_clean=$( echo -e " $line " | sed ' s/\x1b\[[0-9;]*m//g' )
112+ # Count characters as bash sees them
113+ local line_len=${# line_clean}
114+ # Count emojis (each needs +1 for double-width display)
115+ local line_emoji_count=$( count_emojis " $line_clean " )
116+ # Count variation selectors (need to subtract since they don't display)
117+ local line_vs_count=$( count_variation_selectors " $line_clean " )
118+
119+ # Special handling: emojis WITH variation selectors don't need the +1
120+ # because bash already counts them as 2 (emoji + VS), and they display as 2
121+ # So for lines with VS, don't add the emoji count
122+ # Display width = bash_length + emoji_count - (vs_count + vs_count)
123+ # Actually: if VS exists, that emoji shouldn't be counted in emoji_count adjustment
124+ local display_adjustment=$(( line_emoji_count - line_vs_count - line_vs_count))
125+ local actual_display_width=$(( line_len + display_adjustment))
126+
127+ local padding_needed=$(( internal_width - actual_display_width))
128+
129+ # Ensure padding is not negative
130+ if [ $padding_needed -lt 0 ]; then
131+ padding_needed=0
132+ fi
133+
134+ printf " ${border_color} β${NC} "
135+ echo -ne " $line "
136+ printf " %*s" $padding_needed " "
137+ echo -e " ${border_color} β${NC} "
138+ done
139+
140+ # Bottom border
141+ echo -e " ${border_color} β$( printf ' β%.0s' $( seq 1 $(( box_width - 2 )) ) ) β${NC} "
142+ }
143+
40144# Clear screen and start the show
41- clear
145+ # clear
42146
43147# Animated border
44148animate_border
45149
46- echo -e " ${BOLD}${BLUE } "
150+ echo -e " ${BOLD}${GREEN } "
47151echo "
48152βββββββ βββββββββββ βββ ββββββββββββ ββββββ βββββββββββββ βββββββ ββββ βββββββ ββββββββββββββββ ββββββββββββ
49153βββββββββββββββββββ βββ βββββββββββββ ββββββ ββββββββββββββββββββββββββββ ββββββββ ββββββββββββββββββ ββββββββββββ
@@ -87,27 +191,53 @@ echo -e "${CYAN}]${NC}"
87191echo
88192
89193# System info with style
90- echo -e " ${PURPLE}${BOLD} ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ${NC} "
91- echo -e " ${PURPLE}${BOLD} β ${NC} ${BOLD}${WHITE} CONTAINER INFORMATION ${NC} ${PURPLE}${BOLD} β ${NC} "
92- echo -e " ${PURPLE}${BOLD} β βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ£ ${NC} "
93- echo -e " ${PURPLE}${BOLD} β ${NC} ${ CYAN}π³ Container: ${NC} NHS Notify Development Environment ${PURPLE}${BOLD} β ${NC} "
94- echo -e " ${PURPLE}${BOLD} β ${NC} ${ CYAN}π
Date: ${NC} $( date + ' %A, %B %d, %Y ' ) ${PURPLE}${BOLD} β ${NC} "
95- echo -e " ${PURPLE}${BOLD} β ${NC} ${ CYAN}β° Time: ${NC} $( date + ' %H:%M:%S %Z ' ) ${PURPLE}${BOLD} β ${NC} "
96- echo -e " ${PURPLE}${BOLD} β ${NC} ${ CYAN}π€ User: ${NC} $( whoami ) ${PURPLE}${BOLD} β ${NC} "
97- echo -e " ${PURPLE}${BOLD} β ${NC} ${CYAN} π₯οΈ Host: ${NC} $( hostname ) ${PURPLE}${BOLD} β ${NC} "
98- echo -e " ${PURPLE}${BOLD} β ${NC} ${CYAN} π Workspace: ${NC} $( pwd ) ${PURPLE}${BOLD} β ${NC} "
99- echo -e " ${PURPLE}${BOLD} ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ ${NC }"
194+ container_info=(
195+ " ${CYAN} π³ Container: NHS Notify Development Environment ${NC} "
196+ " ${CYAN} π
Date: $( date + ' %A, %B %d, %Y ' ) ${NC} "
197+ " ${CYAN} β° Time: $( date + ' %H:%M:%S %Z ' ) ${NC} "
198+ " ${CYAN} π€ User: $( whoami ) ${NC} "
199+ " ${CYAN} π₯οΈ Host: $( hostname ) ${NC} "
200+ " ${CYAN} π Workspace: $( pwd ) ${NC} "
201+ )
202+
203+ draw_box " ${PURPLE}${BOLD} " " ${BOLD}${WHITE} CONTAINER INFORMATION ${NC} " 80 " ${container_info[@] }"
100204echo
101205
102206# Feature showcase
103207echo -e " ${GREEN}${BOLD} π READY TO DEVELOP WITH:${NC} "
104208echo
105- echo -e " ${YELLOW} β¨ Node.js & npm${NC} - JavaScript/TypeScript development"
106- echo -e " ${YELLOW} π Python & pip${NC} - Python development tools"
107- echo -e " ${YELLOW} π Git${NC} - Version control"
108- echo -e " ${YELLOW} π³ Docker${NC} - Container management"
109- echo -e " ${YELLOW} π VS Code Extensions${NC} - Enhanced development experience"
110- echo -e " ${YELLOW} π§ ESLint & Prettier${NC} - Code formatting and linting"
209+ echo -e " ${YELLOW} π’ Node.js 22.21.0${NC} - JavaScript/TypeScript development with NVM"
210+ echo -e " ${YELLOW} π Python${NC} - Python development tools"
211+ echo -e " ${YELLOW} οΏ½ Go 1.25.3${NC} - Go development environment"
212+ echo -e " ${YELLOW} π Ruby 3.4.7${NC} - Ruby development tools"
213+ echo -e " ${YELLOW} π Git + GitHub CLI${NC} - Version control with gh CLI tools"
214+ echo -e " ${YELLOW} π³ Docker-in-Docker${NC} - Container management & Docker Compose"
215+ echo -e " ${YELLOW} βοΈ AWS CLI 2.31.18${NC} - Amazon Web Services toolkit"
216+ echo -e " ${YELLOW} π¦ ASDF Version Manager${NC} - Multi-language version management"
217+ echo -e " ${YELLOW} οΏ½ Build Essential${NC} - C/C++ compilation tools"
218+ echo -e " ${YELLOW} π οΈ Oh My Zsh${NC} - Enhanced shell with plugins (git, ssh-agent, terraform)"
219+ echo -e " ${YELLOW} π VS Code Extensions${NC} - 30+ productivity extensions pre-installed"
220+ echo -e " ${YELLOW} οΏ½ ESLint & Prettier${NC} - Code formatting and linting"
221+ echo -e " ${YELLOW} π Terraform Support${NC} - Infrastructure as Code tools"
222+ echo -e " ${YELLOW} π GPG & SSH${NC} - Security and authentication tools"
223+ echo -e " ${YELLOW} π Make & Scripts${NC} - NHS Notify repository templates & automation"
224+ echo
225+
226+ # Quick Health Check & Stats
227+ memory_info=$( free -h | awk ' NR==2{printf "Memory: %s/%s (%.1f%%)", $3,$2,$3*100/$2 }' )
228+ disk_info=$( df -h / | awk ' NR==2{printf "Disk: %s/%s (%s used)", $3,$2,$5}' )
229+ cpu_info=" CPU Cores: $( nproc) "
230+ uptime_raw=$( uptime -p | sed ' s/up //' )
231+ uptime_info=" Container uptime: ${uptime_raw} "
232+
233+ health_check=(
234+ " ${GREEN} π§ ${memory_info}${NC} "
235+ " ${GREEN} πΎ ${disk_info}${NC} "
236+ " ${GREEN} β‘ ${cpu_info}${NC} "
237+ " ${GREEN} β±οΈ ${uptime_info}${NC} "
238+ )
239+
240+ draw_box " ${CYAN} " " ${CYAN}${BOLD} π QUICK HEALTH CHECK${NC} " 80 " ${health_check[@]} "
111241echo
112242
113243# Fun message with typewriter effect
@@ -116,21 +246,174 @@ typewriter "π‘ Tip: This environment is optimized for NHS Notify development!"
116246echo -e " ${NC} "
117247echo
118248
249+ # Development Tips
250+ dev_tips=(
251+ " π‘ Tip: Use 'make help' to see available project commands!"
252+ " π Tip: Run 'gh repo view' to quickly check the current repository status!"
253+ " π³ Tip: Use 'docker ps' to see running containers in this environment!"
254+ " π¦ Tip: Run 'asdf list' to see all installed language versions!"
255+ " π§ Tip: Type 'code .' to open the current directory in VS Code!"
256+ " π Tip: Use 'npm run dev' or 'make dev' to start development servers!"
257+ " π Tip: Press Ctrl+\` to open/close the integrated terminal!"
258+ " π Tip: Use 'git log --oneline -10' for a clean commit history view!"
259+ " π Tip: Run 'gh auth status' to check your GitHub authentication!"
260+ " β‘ Tip: Use 'terraform --version' to verify Terraform installation!"
261+ )
262+
263+ random_tip=${dev_tips[$RANDOM % ${#dev_tips[@]} ]}
264+ echo -e " ${GREEN}${random_tip}${NC} "
265+ echo
266+
267+ # Quick Commands Reference
268+ echo -e " ${PURPLE}${BOLD} β‘ QUICK COMMANDS${NC} "
269+ echo -e " ${YELLOW} make help${NC} - Show project-specific commands"
270+ echo -e " ${YELLOW} gh repo view${NC} - View current repository info"
271+ echo -e " ${YELLOW} docker ps${NC} - List running containers"
272+ echo -e " ${YELLOW} asdf current${NC} - Show current language versions"
273+ echo -e " ${YELLOW} aws --version${NC} - Verify AWS CLI installation"
274+ echo
275+
276+ # Time-based greeting with fun elements
277+ current_hour=$( date +%H)
278+ if [ $current_hour -lt 12 ]; then
279+ greeting=" π
Good morning"
280+ mood_emoji=" β"
281+ elif [ $current_hour -lt 17 ]; then
282+ greeting=" βοΈ Good afternoon"
283+ mood_emoji=" π"
284+ else
285+ greeting=" π Good evening"
286+ mood_emoji=" π"
287+ fi
288+
289+ echo -e " ${BOLD}${WHITE}${greeting} , $( whoami) ! ${mood_emoji} Ready to build something amazing?${NC} "
290+ echo
291+
292+ # Fun coding mood indicator
293+ coding_moods=(
294+ " π₯ You're on fire today!"
295+ " β‘ High voltage coding mode activated!"
296+ " π― Laser-focused and ready to ship!"
297+ " π§ Big brain energy detected!"
298+ " π Time to create something brilliant!"
299+ " π Launch sequence initiated!"
300+ " π¨ Ready to paint some beautiful code!"
301+ " π Champion developer mode: ENABLED!"
302+ )
303+
304+ random_mood=${coding_moods[$RANDOM % ${#coding_moods[@]} ]}
305+ echo -e " ${BOLD}${PURPLE}${random_mood}${NC} "
306+ echo
307+
119308# Motivational quote
120309quotes=(
121310 " \" Innovation distinguishes between a leader and a follower.\" - Steve Jobs"
122311 " \" The best time to plant a tree was 20 years ago. The second best time is now.\" - Chinese Proverb"
123312 " \" Code is like humor. When you have to explain it, it's bad.\" - Cory House"
124313 " \" First, solve the problem. Then, write the code.\" - John Johnson"
125314 " \" Experience is the name everyone gives to their mistakes.\" - Oscar Wilde"
315+ " \" Any fool can write code that a computer can understand. Good programmers write code that humans can understand.\" - Martin Fowler"
316+ " \" The only way to go fast is to go well.\" - Robert C. Martin"
317+ " \" Talk is cheap. Show me the code.\" - Linus Torvalds"
318+ " \" Programs must be written for people to read, and only incidentally for machines to execute.\" - Harold Abelson"
319+ " \" The best error message is the one that never shows up.\" - Thomas Fuchs"
320+ " \" Simplicity is the ultimate sophistication.\" - Leonardo da Vinci"
321+ " \" Code never lies, comments sometimes do.\" - Ron Jeffries"
322+ " \" The most important property of a program is whether it accomplishes the intention of its user.\" - C.A.R. Hoare"
323+ " \" Debugging is twice as hard as writing the code in the first place.\" - Brian Kernighan"
324+ " \" Good code is its own best documentation.\" - Steve McConnell"
325+ " \" Make it work, make it right, make it fast.\" - Kent Beck"
326+ " \" The function of good software is to make the complex appear to be simple.\" - Grady Booch"
327+ " \" There are only two hard things in Computer Science: cache invalidation and naming things.\" - Phil Karlton"
328+ " \" Perfection is achieved not when there is nothing more to add, but when there is nothing left to take away.\" - Antoine de Saint-ExupΓ©ry"
329+ " \" Programming is not about typing, it's about thinking.\" - Rich Hickey"
126330)
127331
128332random_quote=${quotes[$RANDOM % ${#quotes[@]} ]}
129333echo -e " ${ITALIC}${BLUE} π ${random_quote}${NC} "
130334echo
131335
132- # Final animated border
133- animate_border
336+ # Fun Achievement System
337+ echo -e " ${YELLOW}${BOLD} π DEVELOPER ACHIEVEMENTS UNLOCKED${NC} "
338+
339+ # Check for various files/conditions and award achievements
340+ achievements=()
341+
342+ if [ -f " package.json" ]; then
343+ achievements+=(" π¦ Node.js Navigator - package.json detected!" )
344+ fi
345+
346+ if [ -f " Dockerfile" ]; then
347+ achievements+=(" π³ Container Captain - Dockerfile found!" )
348+ fi
349+
350+ if [ -f " terraform.tf" ] || [ -f " main.tf" ]; then
351+ achievements+=(" ποΈ Infrastructure Architect - Terraform files detected!" )
352+ fi
353+
354+ if [ -f " Makefile" ]; then
355+ achievements+=(" βοΈ Automation Expert - Makefile ready to roll!" )
356+ fi
357+
358+ if [ -d " .git" ]; then
359+ achievements+=(" π Version Control Virtuoso - Git repository active!" )
360+ fi
361+
362+ if [ -f " README.md" ]; then
363+ achievements+=(" π Documentation Dynamo - README.md present!" )
364+ fi
365+
366+ # Always available achievements
367+ achievements+=(" π― Environment Expert - NHS Notify devcontainer loaded!" )
368+ achievements+=(" β‘ Multi-language Master - Node.js, Python, Go & Ruby ready!" )
369+
370+ # Display random achievements (max 3)
371+ if [ ${# achievements[@]} -gt 0 ]; then
372+ # Shuffle and take up to 3 achievements
373+ for i in $( shuf -i 0-$(( ${# achievements[@]} - 1 )) | head -3) ; do
374+ echo -e " ${CYAN} ${achievements[$i]}${NC} "
375+ done
376+ else
377+ echo -e " ${CYAN} π Ready to unlock your first achievement!${NC} "
378+ fi
379+ echo
380+
381+
382+
383+ # Fun container stats
384+ total_packages=$( dpkg -l | wc -l)
385+ vs_code_extensions=" 30+"
134386
387+ echo -e " ${BOLD}${CYAN} π Container loaded with ${total_packages} packages & ${vs_code_extensions} VS Code extensions!${NC} "
135388echo -e " ${BOLD}${GREEN} π Welcome to your NHS Notify development journey! Happy coding! π${NC} "
136- echo
389+
390+ # Random encouraging message
391+ encouraging_messages=(
392+ " π Every expert was once a beginner. Every pro was once an amateur!"
393+ " πͺ Great things never come from comfort zones!"
394+ " π― Code with purpose, debug with patience, deploy with confidence!"
395+ " π Today's bugs are tomorrow's features (just kidding, fix them)!"
396+ " π₯ Write code that future you will thank present you for!"
397+ " β The best code is code that solves real problems!"
398+ )
399+
400+ random_message=${encouraging_messages[$RANDOM % ${#encouraging_messages[@]} ]}
401+ echo -e " ${ITALIC}${YELLOW}${random_message}${NC} "
402+ echo
403+
404+ # Show current git branch if in a repo
405+ if git rev-parse --git-dir > /dev/null 2>&1 ; then
406+ current_branch=$( git branch --show-current 2> /dev/null || echo " detached" )
407+ echo -e " ${CYAN} πΏ Current branch: ${BOLD}${current_branch}${NC} "
408+
409+ # Check if there are uncommitted changes
410+ if ! git diff-index --quiet HEAD -- 2> /dev/null; then
411+ echo -e " ${YELLOW} β οΈ You have uncommitted changes - don't forget to commit them!${NC} "
412+ fi
413+ fi
414+
415+
416+ echo
417+
418+ # Final animated border
419+ animate_border
0 commit comments