diff --git a/package-lock.json b/package-lock.json index 6bff04c2de66..c63210318f6d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -256,7 +256,7 @@ "memfs": "^4.6.0", "onchange": "^7.1.0", "openai": "^4.47.2", - "patch-package": "^8.0.0", + "patch-package": "^8.1.0-canary.1", "peggy": "^4.0.3", "portfinder": "^1.0.28", "prettier": "^2.8.8", @@ -31759,7 +31759,9 @@ } }, "node_modules/patch-package": { - "version": "8.0.0", + "version": "8.1.0-canary.1", + "resolved": "https://registry.npmjs.org/patch-package/-/patch-package-8.1.0-canary.1.tgz", + "integrity": "sha512-x/O3E5kvN1KS4yFbCITtIAB6kzXLVInT+tlpjsjuKob5Fi7f6quxeMfEsqGe/RScRSXyujNBMuMnV3T0G2PKNw==", "dev": true, "license": "MIT", "dependencies": { @@ -31768,12 +31770,11 @@ "ci-info": "^3.7.0", "cross-spawn": "^7.0.3", "find-yarn-workspace-root": "^2.0.0", - "fs-extra": "^9.0.0", + "fs-extra": "^10.0.0", "json-stable-stringify": "^1.0.2", "klaw-sync": "^6.0.0", "minimist": "^1.2.6", "open": "^7.4.2", - "rimraf": "^2.6.3", "semver": "^7.5.3", "slash": "^2.0.0", "tmp": "^0.0.33", @@ -31832,23 +31833,27 @@ "dev": true, "license": "MIT" }, - "node_modules/patch-package/node_modules/has-flag": { - "version": "4.0.0", + "node_modules/patch-package/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", "dev": true, "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, "engines": { - "node": ">=8" + "node": ">=12" } }, - "node_modules/patch-package/node_modules/rimraf": { - "version": "2.7.1", + "node_modules/patch-package/node_modules/has-flag": { + "version": "4.0.0", "dev": true, - "license": "ISC", - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "license": "MIT", + "engines": { + "node": ">=8" } }, "node_modules/patch-package/node_modules/semver": { diff --git a/package.json b/package.json index eca666ce68d0..3a271e3848fd 100644 --- a/package.json +++ b/package.json @@ -323,7 +323,7 @@ "memfs": "^4.6.0", "onchange": "^7.1.0", "openai": "^4.47.2", - "patch-package": "^8.0.0", + "patch-package": "^8.1.0-canary.1", "peggy": "^4.0.3", "portfinder": "^1.0.28", "prettier": "^2.8.8", diff --git a/scripts/applyPatches.sh b/scripts/applyPatches.sh index 7319d72ffe39..4d6abd8dede7 100755 --- a/scripts/applyPatches.sh +++ b/scripts/applyPatches.sh @@ -4,63 +4,71 @@ # This is useful because patch-package does not fail on errors or warnings by default, # which means that broken patches are easy to miss, and leads to developer frustration and wasted time. -SCRIPTS_DIR=$(dirname "${BASH_SOURCE[0]}") -source "$SCRIPTS_DIR/shellUtils.sh" +OS="$(uname)" +if [[ "$OS" != "Darwin" && "$OS" != "Linux" ]]; then + error "Unsupported OS: $OS" + return 1 +fi -# Wrapper to run patch-package. -function patchPackage { - # See if we're in the HybridApp repo - IS_HYBRID_APP_REPO=$(scripts/is-hybrid-app.sh) - NEW_DOT_FLAG="${STANDALONE_NEW_DOT:-false}" +SCRIPT_DIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &> /dev/null && pwd)" +readonly SCRIPT_DIR +source "$SCRIPT_DIR/shellUtils.sh" + +# See if we're in the HybridApp repo +IS_HYBRID_APP_REPO=$(scripts/is-hybrid-app.sh) +readonly IS_HYBRID_APP_REPO +readonly NEW_DOT_FLAG="${STANDALONE_NEW_DOT:-false}" - OS="$(uname)" - if [[ "$OS" == "Darwin" || "$OS" == "Linux" ]]; then +# Wrapper to run patch-package. +function patchPackage() { if [[ "$IS_HYBRID_APP_REPO" == "true" && "$NEW_DOT_FLAG" == "false" ]]; then TEMP_PATCH_DIR=$(mktemp -d ./tmp-patches-XXX) + trap 'rm -rf "$TEMP_PATCH_DIR"' RETURN + cp -r ./patches/* "$TEMP_PATCH_DIR" cp -r ./Mobile-Expensify/patches/* "$TEMP_PATCH_DIR" - npx patch-package --patch-dir "$TEMP_PATCH_DIR" --error-on-fail --color=always - EXIT_CODE=$? - - rm -rf "$TEMP_PATCH_DIR" + if ! npx patch-package --patch-dir "$TEMP_PATCH_DIR" --error-on-fail --color=always; then + return 1 + fi else - npx patch-package --error-on-fail --color=always - EXIT_CODE=$? + if ! npx patch-package --error-on-fail --color=always; then + return 1 + fi fi - exit $EXIT_CODE - else - error "Unsupported OS: $OS" - exit 1 - fi } # Run patch-package and capture its output and exit code, while still displaying the original output to the terminal -TEMP_OUTPUT="$(mktemp)" -patchPackage 2>&1 | tee "$TEMP_OUTPUT" +OUTPUT="$(mktemp)" +trap 'rm -rf "$OUTPUT"' EXIT +patchPackage 2>&1 | tee "$OUTPUT" EXIT_CODE=${PIPESTATUS[0]} -OUTPUT="$(cat "$TEMP_OUTPUT")" -rm -f "$TEMP_OUTPUT" - -# Check if the output contains a warning message -echo "$OUTPUT" | grep -q "Warning:" -WARNING_FOUND=$? - -printf "\n" +echo # Determine the final exit code -if [ "$EXIT_CODE" -eq 0 ]; then - if [ $WARNING_FOUND -eq 0 ]; then - # patch-package succeeded but warning was found - error "It looks like you upgraded a dependency without upgrading the patch. Please review the patch, determine if it's still needed, and port it to the new version of the dependency." - exit 1 - else - # patch-package succeeded and no warning was found - success "patch-package succeeded without errors or warnings" - exit 0 - fi +if [[ "$EXIT_CODE" -eq 0 ]]; then + # patch-package succeeded, but check for warnings + if grep -q "Warning:" "$OUTPUT"; then + error "It looks like you upgraded a dependency without upgrading the patch. Please review the patch, determine if it's still needed, and port it to the new version of the dependency." + exit 1 + else + success "patch-package succeeded without errors or warnings" + exit 0 + fi else - # patch-package failed - error "patch-package failed to apply a patch" - exit "$EXIT_CODE" + ERROR_PATCHES_HAVE_FAILED=$(sed 's/\x1b\[[0-9;]*m//g' < "$OUTPUT" | awk '/The patches for/ {print $4}' | grep -v '^$' | sort -u) + if [[ -n "$ERROR_PATCHES_HAVE_FAILED" ]]; then + error "patch-package failed to apply one or more patches, cleaning failed packages and trying once again." + for PACKAGE in $ERROR_PATCHES_HAVE_FAILED; do + info "patch failed to apply for $PACKAGE. Removing it before reinstall..." + rm -rf "$SCRIPT_DIR/../node_modules/$PACKAGE" + done + npm install --ignore-scripts + if ! patchPackage; then + error "patch-package failed after retry, giving up" + exit 1 + fi + fi + error "patch-package failed" + exit 1 fi