Skip to content

Commit 9b2fbb0

Browse files
seefoodclaude
andcommitted
Add interactive update prompt and colorful output to doctor
Enhancements to the bash-it doctor command: **Interactive Update Prompt:** - Offers to update bash-it when behind remote master - Only prompts when safe (no uncommitted changes, can fast-forward) - Performs git merge with --ff-only for safety - Provides clear feedback on update status **Colorful Output:** - Color-coded sections (cyan headers, green labels, yellow warnings) - Visual indicators (✓ for up-to-date status) - Improved readability for terminal output **Better Configuration Detection:** - Now greps ALL common config files (.bashrc, .bash_profile, .profile) - Shows bash-it loading context from each file found - Previously only checked single config file **Improved Version Display:** - Shows commits ahead of latest tag (e.g., "v3.1.2 +3") - Clearer version information for users not on tagged releases **Documentation Updates:** - Updated bug_report.yml to streamline diagnostic info collection - Added Diagnostics section to README - Emphasizes using `bash-it doctor` for bug reports Related to issue #1745 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent 177f706 commit 9b2fbb0

File tree

3 files changed

+133
-61
lines changed

3 files changed

+133
-61
lines changed

.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 17 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -36,48 +36,32 @@ body:
3636
Provide a link to a live example, or an unambiguous set of steps to reproduce this bug. Include code to reproduce, if relevant.
3737
validations:
3838
required: true
39-
- type: input
40-
attributes:
41-
label: Bash-it version
42-
placeholder: "How to get: bash-it version"
43-
validations:
44-
required: true
45-
- type: input
46-
attributes:
47-
label: List of enabled plugins, themes and aliases
48-
placeholder: "How to get: bash-it show plugins|themes|aliases (it is not a pipe)"
49-
validations:
50-
required: true
51-
- type: input
52-
attributes:
53-
label: Bash version
54-
placeholder: "How to get: bash --version"
55-
validations:
56-
required: true
57-
- type: input
58-
attributes:
59-
label: Operating system and version
60-
placeholder: "How to get: neofetch (or another command)"
61-
validations:
62-
required: true
6339
- type: textarea
6440
attributes:
65-
label: "bash-it doctor output"
41+
label: "Diagnostic Information"
42+
description: >
43+
**Please run `bash-it doctor` and paste the complete output below.**
44+
This single command provides all the diagnostic information we need including:
45+
bash-it version, enabled components, bash version, OS version, and configuration.
46+
placeholder: "Run: bash-it doctor"
6647
value: |
6748
```
68-
# How to get: bash-it doctor
49+
# Paste the output of: bash-it doctor
50+
51+
6952
```
7053
validations:
71-
required: false
54+
required: true
7255
- type: textarea
7356
attributes:
74-
label: Your ~/.bashrc
75-
value: |
76-
```bash
77-
# How to get: cat ~/.bashrc
78-
```
57+
label: "Additional Context (Optional)"
58+
description: >
59+
Any additional information that might help diagnose the issue.
60+
This could include specific error messages, relevant parts of your ~/.bashrc,
61+
or other configuration details not captured by `bash-it doctor`.
62+
placeholder: "Paste any additional relevant information here"
7963
validations:
80-
required: true
64+
required: false
8165
- type: textarea
8266
attributes:
8367
label: Notes

docs/README.md

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ Stop polluting your `~/bin` directory and your `.bashrc` file, fork/clone Bash-i
2121
- [via Docker](https://bash-it.readthedocs.io/en/latest/installation/#install-using-docker)
2222
- [Updating](https://bash-it.readthedocs.io/en/latest/installation/#updating)
2323
- [Help](https://bash-it.readthedocs.io/en/latest/misc/#help-screens)
24+
- [Diagnostics](#diagnostics)
2425
- [Search](https://bash-it.readthedocs.io/en/latest/commands/search)
2526
- [Syntax](https://bash-it.readthedocs.io/en/latest/commands/search/#syntax)
2627
- [Searching with Negations](
@@ -54,10 +55,30 @@ If this is undesirable, you can create another file, by run the installer:
5455
BASH_IT_CONFIG_FILE=path/to/my/custom/location.bash ~/.bash_it/install.sh
5556
```
5657

58+
## Diagnostics
59+
60+
If you're experiencing issues with Bash-it or need to report a bug, use the built-in diagnostics tool:
61+
62+
```bash
63+
bash-it doctor
64+
```
65+
66+
This command provides a comprehensive summary including:
67+
- Environment information (OS, Bash version)
68+
- Bash-it version and update status
69+
- Configuration file locations and how Bash-it is loaded
70+
- List of enabled components (aliases, plugins, completions)
71+
72+
**When reporting bugs**, please include the full output of `bash-it doctor` in your issue report.
73+
74+
The doctor command can also help you update Bash-it - if you're behind the latest version and it's safe to update, you'll be prompted to merge the latest changes.
75+
5776
## Contributing
5877

5978
Please take a look at the [Contribution Guidelines](https://bash-it.readthedocs.io/en/latest/contributing) before reporting a bug or providing a new feature.
6079

80+
**When reporting bugs**, always run `bash-it doctor` and include its output in your issue report to help maintainers diagnose the problem quickly.
81+
6182
The [Development Guidelines](https://bash-it.readthedocs.io/en/latest/development) have more information on some of the internal workings of Bash-it,
6283
please feel free to read through this page if you're interested in how Bash-it loads its components.
6384

lib/helpers.bash

Lines changed: 95 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -420,15 +420,23 @@ function _bash-it-doctor-summary() {
420420

421421
local component_type enabled_count enabled_list f component_name
422422

423-
echo "Bash-it Doctor Summary"
424-
echo "======================"
423+
# Color definitions
424+
local BOLD CYAN GREEN YELLOW RESET
425+
BOLD=$(tput bold 2> /dev/null || echo "")
426+
CYAN=$(tput setaf 6 2> /dev/null || echo "")
427+
GREEN=$(tput setaf 2 2> /dev/null || echo "")
428+
YELLOW=$(tput setaf 3 2> /dev/null || echo "")
429+
RESET=$(tput sgr0 2> /dev/null || echo "")
430+
431+
echo "${BOLD}${CYAN}Bash-it Doctor Summary${RESET}"
432+
echo "${CYAN}======================${RESET}"
425433
echo ""
426434

427435
# Environment Information
428-
echo "## Environment"
429-
echo "OS: $(uname -s) $(uname -r)"
430-
echo "Bash Version: ${BASH_VERSION}"
431-
echo "Bash-it Location: ${BASH_IT}"
436+
echo "${BOLD}## Environment${RESET}"
437+
echo "${GREEN}OS:${RESET} $(uname -s) $(uname -r)"
438+
echo "${GREEN}Bash Version:${RESET} ${BASH_VERSION}"
439+
echo "${GREEN}Bash-it Location:${RESET} ${BASH_IT}"
432440

433441
# Check which config file is used
434442
local config_file
@@ -441,27 +449,34 @@ function _bash-it-doctor-summary() {
441449
else
442450
config_file="unknown"
443451
fi
444-
echo "Config File: ${config_file}"
452+
echo "${GREEN}Config File:${RESET} ${config_file}"
445453
echo ""
446454

447455
# Bash-it Version Information
448-
echo "## Bash-it Version"
456+
echo "${BOLD}## Bash-it Version${RESET}"
449457
pushd "${BASH_IT}" > /dev/null 2>&1 || {
450458
echo "Error: Cannot access Bash-it directory"
451459
return 1
452460
}
453461

454-
local current_commit current_tag commits_behind
462+
local current_commit current_tag commits_behind latest_tag commits_since_tag
455463
current_commit="$(git rev-parse --short HEAD 2> /dev/null || echo 'unknown')"
456464
current_tag="$(git describe --exact-match --tags 2> /dev/null || echo 'none')"
457465

458466
if [[ -z "${BASH_IT_REMOTE:-}" ]]; then
459467
BASH_IT_REMOTE="origin"
460468
fi
461469

462-
echo "Current Commit: ${current_commit}"
470+
# Get version info relative to tags
471+
latest_tag="$(git describe --tags --abbrev=0 2> /dev/null || echo 'none')"
472+
commits_since_tag="$(git rev-list --count "${latest_tag}..HEAD" 2> /dev/null || echo '0')"
473+
463474
if [[ "${current_tag}" != "none" ]]; then
464-
echo "Current Tag: ${current_tag}"
475+
echo "${GREEN}Current Version:${RESET} ${current_tag} (${current_commit})"
476+
elif [[ "${latest_tag}" != "none" && "${commits_since_tag}" != "0" ]]; then
477+
echo "${GREEN}Current Version:${RESET} ${latest_tag} +${commits_since_tag} (${current_commit})"
478+
else
479+
echo "${GREEN}Current Commit:${RESET} ${current_commit}"
465480
fi
466481

467482
# Check how far behind we are
@@ -472,30 +487,82 @@ function _bash-it-doctor-summary() {
472487
commits_behind="$(git rev-list --count HEAD.."${BASH_IT_REMOTE}/${BASH_IT_DEVELOPMENT_BRANCH}" 2> /dev/null || echo 'unknown')"
473488

474489
if [[ "${commits_behind}" == "0" ]]; then
475-
echo "Status: Up to date with ${BASH_IT_REMOTE}/${BASH_IT_DEVELOPMENT_BRANCH}"
490+
echo "${GREEN}Status:${RESET} Up to date with ${BASH_IT_REMOTE}/${BASH_IT_DEVELOPMENT_BRANCH}"
476491
elif [[ "${commits_behind}" != "unknown" ]]; then
477-
echo "Status: ${commits_behind} commits behind ${BASH_IT_REMOTE}/${BASH_IT_DEVELOPMENT_BRANCH}"
492+
echo "${YELLOW}Status:${RESET} ${commits_behind} commits behind ${BASH_IT_REMOTE}/${BASH_IT_DEVELOPMENT_BRANCH}"
493+
494+
# Offer to update if behind and it's safe to do so
495+
local git_status untracked_files merge_base can_ff
496+
git_status="$(git status --porcelain 2> /dev/null)"
497+
untracked_files="$(echo "$git_status" | grep -c '^??' || true)"
498+
499+
# Check if we can fast-forward
500+
merge_base="$(git merge-base HEAD "${BASH_IT_REMOTE}/${BASH_IT_DEVELOPMENT_BRANCH}" 2> /dev/null)"
501+
can_ff=false
502+
if [[ "$(git rev-parse HEAD 2> /dev/null)" == "$merge_base" ]]; then
503+
can_ff=true
504+
fi
505+
506+
# Only offer merge if:
507+
# 1. No modified/staged files (untracked are OK)
508+
# 2. Can fast-forward OR no untracked files that would conflict
509+
if ! echo "$git_status" | grep -v '^??' -q; then
510+
if [[ "$can_ff" == "true" ]] || [[ "$untracked_files" == "0" ]]; then
511+
echo ""
512+
echo "Would you like to update now? This will merge ${BASH_IT_REMOTE}/${BASH_IT_DEVELOPMENT_BRANCH} into your current branch."
513+
read -r -p "Update? [y/N] " response
514+
case "$response" in
515+
[yY] | [yY][eE][sS])
516+
echo "Updating bash-it..."
517+
if git merge "${BASH_IT_REMOTE}/${BASH_IT_DEVELOPMENT_BRANCH}" --ff-only 2> /dev/null; then
518+
echo "✓ Successfully updated to latest version!"
519+
echo ""
520+
echo "Please restart your shell or run: source ~/.bashrc"
521+
else
522+
echo "✗ Fast-forward merge failed. Please run 'bash-it update' for a guided update."
523+
fi
524+
;;
525+
*)
526+
echo "Skipping update. You can update later with: bash-it update"
527+
;;
528+
esac
529+
else
530+
echo ""
531+
echo "Note: Cannot safely auto-update (untracked files may conflict). Use: bash-it update"
532+
fi
533+
else
534+
echo ""
535+
echo "Note: Cannot auto-update (uncommitted changes present). Use: bash-it update"
536+
fi
478537
fi
479538

480539
popd > /dev/null 2>&1 || true
481540
echo ""
482541

483542
# Bash-it Loading Configuration
484-
echo "## Bash-it Loading"
485-
if [[ "${config_file}" != "unknown" && -f "${config_file}" ]]; then
486-
echo "From ${config_file}:"
487-
if grep -i "bash.it\|bash_it" "${config_file}" > /dev/null 2>&1; then
488-
grep -n -i "bash.it\|bash_it" -B2 -A2 "${config_file}" 2> /dev/null || echo " (no bash-it references found)"
489-
else
490-
echo " (no bash-it references found)"
491-
fi
543+
echo "${BOLD}## Bash-it Loading${RESET}"
544+
local config_files_to_check=()
545+
local config_file_path
546+
547+
# Check all common config files
548+
for config_file_path in "${HOME}/.bashrc" "${HOME}/.bash_profile" "${HOME}/.profile"; do
549+
[[ -f "$config_file_path" ]] && config_files_to_check+=("$config_file_path")
550+
done
551+
552+
if [[ ${#config_files_to_check[@]} -gt 0 ]]; then
553+
for config_file_path in "${config_files_to_check[@]}"; do
554+
if grep -i "bash.it\|bash_it" "$config_file_path" > /dev/null 2>&1; then
555+
echo "From ${config_file_path}:"
556+
grep -n -i "bash.it\|bash_it" -B2 -A2 "$config_file_path" 2> /dev/null
557+
echo ""
558+
fi
559+
done
492560
else
493-
echo "Config file not found or unknown"
561+
echo "No config files found (.bashrc, .bash_profile, .profile)"
494562
fi
495-
echo ""
496563

497564
# Enabled Components Summary
498-
echo "## Enabled Components"
565+
echo "${BOLD}## Enabled Components${RESET}"
499566

500567
# Process each component type
501568
for component_type in aliases plugins completion; do
@@ -522,15 +589,15 @@ function _bash-it-doctor-summary() {
522589
fi
523590
done
524591

525-
# Display the summary
592+
# Display the summary with colors
526593
if [[ $enabled_count -eq 0 ]]; then
527-
printf '%s (%d): %s\n' "$display_type" "$enabled_count" "none"
594+
printf '%s%s%s (%s): %s\n' "$CYAN" "$display_type" "$RESET" "$enabled_count" "${YELLOW}none${RESET}"
528595
else
529-
printf '%s (%d): %s\n' "$display_type" "$enabled_count" "${enabled_list[*]}"
596+
printf '%s%s%s (%s): %s\n' "$CYAN" "$display_type" "$RESET" "$enabled_count" "${enabled_list[*]}"
530597
fi
531598
done
532599
echo ""
533-
echo "To copy this report: bash-it doctor summary | pbcopy (macOS) or xclip (Linux)"
600+
echo "${YELLOW}Tip:${RESET} To copy this report: ${CYAN}bash-it doctor${RESET} | pbcopy (macOS) or xclip (Linux)"
534601
}
535602

536603
function _bash-it-doctor-() {

0 commit comments

Comments
 (0)