| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189 |
- #!/usr/bin/env bash
- export VSCODE_QUALITY="stable"
- while getopts ":i" opt; do
- case "$opt" in
- i)
- export VSCODE_QUALITY="insider"
- ;;
- *)
- ;;
- esac
- done
- generate_rejects() {
- local PATCH_FILE="$1"
- if ! command -v python3 >/dev/null 2>&1; then
- echo "python3 not found; cannot create reject files for ${PATCH_FILE}"
- return 1
- fi
- PATCH_FOR_REJECT="${PATCH_FILE}" python3 <<'PY'
- import os
- import pathlib
- import re
- import subprocess
- def chunk_needs_reject(raw_chunk: str) -> bool:
- """Return True when a patch chunk cannot be applied nor reversed."""
- chunk = raw_chunk if raw_chunk.endswith("\n") else raw_chunk + "\n"
- def _run_git(extra_args):
- return subprocess.run(
- ["git", "apply", "--check", "--ignore-whitespace", *extra_args],
- input=chunk,
- text=True,
- capture_output=True,
- )
- forward = _run_git([])
- if forward.returncode == 0:
- return False
- reverse = _run_git(["--reverse"])
- if reverse.returncode == 0:
- return False
- return True
- patch_path = os.environ["PATCH_FOR_REJECT"]
- with open(patch_path, "r", encoding="utf-8", errors="ignore") as src:
- content = src.read()
- chunks = re.split(r'(?m)^diff --git ', content)
- for chunk in chunks:
- chunk = chunk.strip()
- if not chunk:
- continue
- chunk = "diff --git " + chunk
- match = re.search(r'^diff --git a/(.*?) b/(.*?)$', chunk, re.MULTILINE)
- if not match:
- continue
- a_path, b_path = match.groups()
- candidate = b_path if b_path != "/dev/null" else a_path
- if candidate in ("/dev/null", ""):
- continue
- if candidate.startswith("../") or candidate.startswith("..\\") or candidate.startswith("/"):
- continue
- dest = pathlib.Path(candidate + ".rej")
- if not chunk_needs_reject(chunk):
- continue
- dest.parent.mkdir(parents=True, exist_ok=True)
- with dest.open("w", encoding="utf-8") as fh:
- fh.write(chunk)
- if not chunk.endswith("\n"):
- fh.write("\n")
- print(f"generated reject: {dest}")
- PY
- }
- check_file() {
- while [ $# -gt 1 ]; do
- git apply --reject "${1}"
- shift
- done
- if [[ -f "${1}.bak" ]]; then
- mv -f $1{.bak,}
- fi
- if [[ -f "${1}" ]]; then
- git apply --reject "../patches/helper/settings.patch"
- git add .
- git commit --no-verify -q -m "VSCODIUM HELPER"
- echo applying patch: "${1}"
- if ! git apply --ignore-whitespace "${1}"; then
- echo failed to apply patch "${1}"
- git apply --reject --verbose "${1}"
- if [[ -z "$( find . -name '*.rej' -print )" ]]; then
- echo "no .rej generated by git; creating fallback rejects for ${1}"
- if ! generate_rejects "${1}"; then
- echo "failed to generate reject files for ${1}"
- exit 1
- fi
- if [[ -z "$( find . -name '*.rej' -print )" ]]; then
- echo "still no .rej after attempting to create them for ${1}"
- exit 1
- fi
- fi
- while [[ -n "$( find . -name '*.rej' -print )" ]]; do
- read -rp "Press any key when the conflict have been resolved..." -n1 -s
- echo
- done
- git restore .vscode/settings.json
- git add .
- git diff --staged -U1 > "${1}"
- fi
- git add .
- git reset -q --hard HEAD~
- fi
- }
- cd vscode || { echo "'vscode' dir not found"; exit 1; }
- git add .
- git reset -q --hard HEAD
- while [[ -n "$( git log -1 | grep "VSCODIUM HELPER" )" ]]; do
- git reset -q --hard HEAD~
- done
- for FILE in ../patches/*.patch; do
- if [[ "${FILE}" == *"/fix-policies.patch" ]]; then
- check_file "../patches/fix-keymap.patch" "../patches/fix-policies.patch"
- else
- check_file "${FILE}"
- fi
- done
- if [[ "${VSCODE_QUALITY}" == "insider" ]]; then
- for FILE in ../patches/insider/*.patch; do
- check_file "${FILE}"
- done
- fi
- for ARCH in alpine linux osx windows; do
- for FILE in "../patches/${ARCH}/"*.patch; do
- if [[ "${ARCH}" == "linux" && "${FILE}" == *"/arch-"* ]] || [[ "${ARCH}" == "linux" && "${FILE}" == *"/fix-dependencies.patch" ]] || [[ "${ARCH}" == "windows" && "${FILE}" == *"/cli"* ]]; then
- echo "skip ${FILE}"
- else
- check_file "${FILE}"
- fi
- done
- if [[ "${ARCH}" == "linux" ]]; then
- check_file "../patches/optional-tree-sitter.patch" "../patches/linux/fix-dependencies.patch"
- check_file "../patches/cli.patch" "../patches/linux/arch-0-support.patch"
- check_file "../patches/cli.patch" "../patches/linux/arch-0-support.patch" "../patches/linux/arch-1-ppc64le.patch"
- check_file "../patches/cli.patch" "../patches/linux/arch-0-support.patch" "../patches/linux/arch-1-ppc64le.patch" "../patches/linux/arch-2-riscv64.patch"
- check_file "../patches/cli.patch" "../patches/linux/arch-0-support.patch" "../patches/linux/arch-1-ppc64le.patch" "../patches/linux/arch-2-riscv64.patch" "../patches/linux/arch-3-loong64.patch"
- check_file "../patches/cli.patch" "../patches/linux/arch-0-support.patch" "../patches/linux/arch-1-ppc64le.patch" "../patches/linux/arch-2-riscv64.patch" "../patches/linux/arch-3-loong64.patch" "../patches/linux/arch-4-s390x.patch"
- elif [[ "${ARCH}" == "windows" ]]; then
- check_file "../patches/cli.patch" "../patches/windows/cli.patch"
- fi
- for TARGET in client reh; do
- for FILE in "../patches/${ARCH}/${TARGET}/"*.patch; do
- check_file "${FILE}"
- done
- for FILE in "../patches/${ARCH}/${TARGET}/"*/*.patch; do
- check_file "${FILE}"
- done
- done
- done
|