#!/usr/bin/env bash set -euo pipefail script_dir="$(cd "$(dirname "$0")" && pwd -P)" project_root="$(cd "$script_dir/.." && pwd -P)" operational_files=( "$script_dir/check_macos_entrypoints.sh" "$script_dir/macos_helpers.sh" "$script_dir/run_macos.sh" "$script_dir/package_macos.sh" "$script_dir/build_macos.sh" "$project_root/一键运行.command" "$project_root/一键打包.command" "$project_root/run_macos.command" "$project_root/package_macos.command" ) for file in "${operational_files[@]}"; do [[ -f "$file" ]] || { printf 'Missing macOS entry file: %s\n' "$file" >&2; exit 1; } /bin/bash -n "$file" [[ -x "$file" ]] || { printf 'macOS entry is not executable: %s\n' "$file" >&2; exit 1; } done # A Windows checkout can report every shell file as executable even when Git # records mode 100644. Check the index as well so a fresh macOS clone retains # Finder/CLI launchability. Source archives without .git still use the -x gate # above. if command -v git >/dev/null 2>&1 && \ git -C "$project_root" rev-parse --is-inside-work-tree >/dev/null 2>&1 && \ git -C "$project_root" ls-files --error-unmatch -- \ packaging/doctor_workstation.spec >/dev/null 2>&1; then for file in "${operational_files[@]}"; do relative_path="${file#"$project_root"/}" index_record="$(git -C "$project_root" ls-files --stage -- "$relative_path")" index_mode="${index_record%% *}" [[ "$index_mode" == "100755" ]] || { printf 'Git index mode must be 100755 for macOS entry: %s (found %s)\n' \ "$relative_path" "${index_mode:-untracked}" >&2 exit 1 } done fi open_line="$(grep -nF '/usr/bin/open "$artifact"' "$script_dir/run_macos.sh" | head -n 1 | cut -d: -f1)" source_line="$(grep -nF 'macos_ensure_uv' "$script_dir/run_macos.sh" | head -n 1 | cut -d: -f1)" [[ -n "$open_line" && -n "$source_line" && "$open_line" -lt "$source_line" ]] || { echo 'Built .app must be opened before source-environment preparation.' >&2 exit 1 } grep -Fq 'sync --locked' "$script_dir/run_macos.sh" grep -Fq 'sync --locked --extra build' "$script_dir/package_macos.sh" grep -Fq 'ci --prefix "$project_root/video_companion"' "$script_dir/package_macos.sh" grep -Fq '/bin/bash "$script_dir/build_macos.sh"' "$script_dir/package_macos.sh" grep -Fq 'SHASUMS256.txt' "$script_dir/package_macos.sh" grep -Fq '/usr/bin/ditto -c -k --sequesterRsrc --keepParent' "$script_dir/package_macos.sh" grep -Fq '/usr/bin/shasum -a 256' "$script_dir/package_macos.sh" grep -Fq 'scripts/run_macos.sh' "$project_root/一键运行.command" grep -Fq 'scripts/run_macos.sh' "$project_root/run_macos.command" grep -Fq 'scripts/package_macos.sh' "$project_root/一键打包.command" grep -Fq 'scripts/package_macos.sh' "$project_root/package_macos.command" if grep -En '(^|[[:space:]])(export[[:space:]]+)?HOME=' "${operational_files[@]:1}"; then echo 'macOS entry scripts must not repurpose HOME.' >&2 exit 1 fi if grep -Ein 'SDKSecret(Key)?|UserSig|userSig' "${operational_files[@]:1}"; then echo 'macOS entry scripts must not contain RTC secrets or credentials.' >&2 exit 1 fi set +e trap_output="$( CI=1 DOCTOR_NONINTERACTIVE=1 /bin/bash -c ' source "$1" macos_install_exit_trap 1 exit 7 ' macos-contract "$script_dir/macos_helpers.sh" 2>&1 )" trap_status=$? set -e [[ "$trap_status" -eq 7 ]] || { printf 'Non-interactive failure trap changed exit status to %s.\n' "$trap_status" >&2 exit 1 } grep -Fq '操作失败' <<<"$trap_output" echo 'macOS entrypoint contracts passed.'