Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-bash-libs
ref: d62e8c1fec2de9148bc832977c206b9f1827dd19
ref: 424ef9fe61bc8a462ba9980ea63b38dd202ec242
path: .dependencies/base-bash-libs

- name: Install BATS
Expand Down Expand Up @@ -91,7 +91,7 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-bash-libs
ref: d62e8c1fec2de9148bc832977c206b9f1827dd19
ref: 424ef9fe61bc8a462ba9980ea63b38dd202ec242
path: .dependencies/base-bash-libs

- name: Set up Python
Expand Down Expand Up @@ -167,7 +167,7 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-bash-libs
ref: d62e8c1fec2de9148bc832977c206b9f1827dd19
ref: 424ef9fe61bc8a462ba9980ea63b38dd202ec242
path: .dependencies/base-bash-libs

- name: Set up Python
Expand Down Expand Up @@ -210,7 +210,7 @@ jobs:
- uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
with:
repository: basefoundry/base-bash-libs
ref: d62e8c1fec2de9148bc832977c206b9f1827dd19
ref: 424ef9fe61bc8a462ba9980ea63b38dd202ec242
path: .dependencies/base-bash-libs

- name: Expose reusable Bash library checkout as sibling
Expand Down
114 changes: 27 additions & 87 deletions cli/bash/commands/basectl/subcommands/update_profile.sh
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ base_update_profile_usage_error() {

base_update_profile_source_file_library() {
import_base_lib file/lib_file.sh
assert_function_exists file_section_exists file_section_needs_update
}

base_update_profile_shell_double_quote() {
Expand Down Expand Up @@ -162,102 +163,25 @@ base_update_profile_backup_existing_file() {
cp -p "$target_file" "$backup_path" || fatal_error "Unable to back up '$target_file' to '$backup_path'."
}

base_update_profile_write_section_content() {
local snippet_name="$1"
local output_file="$2"
local lines=()

mapfile -t lines < <(base_update_profile_section_lines "$snippet_name") || return 1
printf '%s\n' "${lines[@]}" > "$output_file"
}

base_update_profile_existing_section_content() {
local target_file="$1"
local start_marker="$2"
local end_marker="$3"
local output_file="$4"

awk -v START_M="$start_marker" -v END_M="$end_marker" '
BEGIN {
in_section = 0
processed = 0
}
$0 == START_M && processed == 0 {
in_section = 1
next
}
$0 == END_M && in_section == 1 {
processed = 1
exit
}
in_section == 1 {
print $0
}
END {
if (processed == 0) {
exit 1
}
}
' "$target_file" > "$output_file"
}

base_update_profile_update_file_needs_change() {
local target_file="$1"
local snippet_name="$2"
local start_marker="$3"
local end_marker="$4"
local current_content_file
local desired_content_file
local start_count
local end_count
local lines=()

[[ -f "$target_file" ]] || return 0

start_count="$(grep -cxF -- "$start_marker" "$target_file" || true)"
end_count="$(grep -cxF -- "$end_marker" "$target_file" || true)"
if ((start_count == 0 && end_count == 0)); then
return 0
fi
if ((start_count != end_count)); then
return 0
fi

std_make_temp_file current_content_file base-profile-current ||
fatal_error "Unable to create temporary section content file for '$target_file'."
std_make_temp_file desired_content_file base-profile-desired || {
fatal_error "Unable to create temporary desired content file for '$target_file'."
}

if ! base_update_profile_existing_section_content "$target_file" "$start_marker" "$end_marker" "$current_content_file"; then
rm -f "$current_content_file" "$desired_content_file"
return 0
fi
base_update_profile_write_section_content "$snippet_name" "$desired_content_file" || {
rm -f "$current_content_file" "$desired_content_file"
return 1
}

if cmp -s "$current_content_file" "$desired_content_file"; then
rm -f "$current_content_file" "$desired_content_file"
return 1
fi

rm -f "$current_content_file" "$desired_content_file"
return 0
mapfile -t lines < <(base_update_profile_section_lines "$snippet_name") || return 2
file_section_needs_update "$target_file" "$start_marker" "$end_marker" "${lines[@]}"
}

base_update_profile_remove_file_needs_change() {
local target_file="$1"
local start_marker="$2"
local end_marker="$3"
local start_count
local end_count

[[ -f "$target_file" ]] || return 1

start_count="$(grep -cxF -- "$start_marker" "$target_file" || true)"
end_count="$(grep -cxF -- "$end_marker" "$target_file" || true)"
((start_count > 0 || end_count > 0))
file_section_exists "$target_file" "$start_marker" "$end_marker"
}

base_update_profile_update_file() {
Expand All @@ -273,9 +197,17 @@ base_update_profile_update_file() {
end_marker="$(base_update_profile_end_marker "$snippet_name")" || return 1
mapfile -t lines < <(base_update_profile_section_lines "$snippet_name") || return 1

if ! base_update_profile_update_file_needs_change "$target_file" "$snippet_name" "$start_marker" "$end_marker"; then
return 0
fi
base_update_profile_update_file_needs_change "$target_file" "$snippet_name" "$start_marker" "$end_marker"
case $? in
0)
;;
1)
return 0
;;
*)
return 1
;;
esac

if ((dry_run)); then
base_update_profile_backup_existing_file "$target_file" "$backup_timestamp" "$dry_run" || return 1
Expand All @@ -300,9 +232,17 @@ base_update_profile_remove_file() {
start_marker="$(base_update_profile_start_marker "$snippet_name")" || return 1
end_marker="$(base_update_profile_end_marker "$snippet_name")" || return 1

if ! base_update_profile_remove_file_needs_change "$target_file" "$start_marker" "$end_marker"; then
return 0
fi
base_update_profile_remove_file_needs_change "$target_file" "$start_marker" "$end_marker"
case $? in
0)
;;
1)
return 0
;;
*)
return 1
;;
esac

if ((dry_run)); then
base_update_profile_backup_existing_file "$target_file" "$backup_timestamp" "$dry_run" || return 1
Expand Down
65 changes: 65 additions & 0 deletions cli/bash/commands/basectl/tests/update-profile.bats
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,71 @@ EOF
[[ "$(cat "$TEST_HOME/.zprofile"; printf marker)" == "marker" ]]
}

@test "update-profile update detection delegates to shared file section helper" {
local bash_libs_dir

bash_libs_dir="$(base_bash_libs_fixture_dir)"
touch "$TEST_HOME/.bashrc"

run env \
HOME="$TEST_HOME" \
BASE_HOME="$BASE_REPO_ROOT" \
BASE_BASH_LIBS_DIR="$bash_libs_dir" \
bash -c '
source "$BASE_HOME/base_init.sh"
source "$BASE_HOME/cli/bash/commands/basectl/subcommands/update_profile.sh"
base_update_profile_source_file_library
file_section_needs_update() {
printf "helper_target=%s\n" "$1"
printf "helper_start=%s\n" "$2"
printf "helper_end=%s\n" "$3"
shift 3
printf "helper_content=%s\n" "$*"
return 1
}
base_update_profile_update_file_needs_change "$HOME/.bashrc" bashrc "# >>> base: bashrc managed >>>" "# <<< base: bashrc managed <<<"
printf "change_status=%s\n" "$?"
'

[ "$status" -eq 0 ]
[[ "$output" == *"helper_target=$TEST_HOME/.bashrc"* ]]
[[ "$output" == *"helper_start=# >>> base: bashrc managed >>>"* ]]
[[ "$output" == *"helper_end=# <<< base: bashrc managed <<<"* ]]
[[ "$output" == *"source \"$BASE_REPO_ROOT/lib/shell/bashrc\""* ]]
[[ "$output" == *"change_status=1"* ]]
}

@test "update-profile remove detection delegates to shared file section helper" {
local bash_libs_dir

bash_libs_dir="$(base_bash_libs_fixture_dir)"
touch "$TEST_HOME/.bashrc"

run env \
HOME="$TEST_HOME" \
BASE_HOME="$BASE_REPO_ROOT" \
BASE_BASH_LIBS_DIR="$bash_libs_dir" \
bash -c '
source "$BASE_HOME/base_init.sh"
source "$BASE_HOME/cli/bash/commands/basectl/subcommands/update_profile.sh"
base_update_profile_source_file_library
file_section_exists() {
printf "helper_target=%s\n" "$1"
printf "helper_start=%s\n" "$2"
printf "helper_end=%s\n" "$3"
return 0
}
base_update_profile_remove_file_needs_change "$HOME/.bashrc" "# >>> base: bashrc managed >>>" "# <<< base: bashrc managed <<<"
printf "change_status=%s\n" "$?"
'

[ "$status" -eq 0 ]
[[ "$output" == *"helper_target=$TEST_HOME/.bashrc"* ]]
[[ "$output" == *"helper_start=# >>> base: bashrc managed >>>"* ]]
[[ "$output" == *"helper_end=# <<< base: bashrc managed <<<"* ]]
[[ "$output" == *"change_status=0"* ]]
}

@test "basectl update-profile explains BASE_HOME mismatch recovery" {
local runtime_base="$TEST_TMPDIR/runtime-base"
local resolved_base="$TEST_TMPDIR/resolved-base"
Expand Down
Loading