|
17 | 17 | # Modify a .xcodeproj to use a specific branch, version, or commit for the
|
18 | 18 | # firebase-ios-sdk SPM dependency.
|
19 | 19 |
|
20 |
| -set -euo pipefail |
21 |
| - |
22 |
| -# --- Helper functions --- |
23 |
| -usage() { |
24 |
| - echo "Usage: $0 <path_to.xcodeproj> [--version <version> | --revision <revision> | --prerelease]" |
25 |
| - echo "Example: $0 path/to/MyProject.xcodeproj --version 10.24.0" |
26 |
| - exit 1 |
27 |
| -} |
| 20 | +set -xeuo pipefail |
28 | 21 |
|
29 | 22 | # --- Argument parsing ---
|
30 | 23 | if [[ $# -lt 2 ]]; then
|
31 |
| - usage |
| 24 | + echo "Modify a .xcodeproj to use a specific branch, version, or commit for the" |
| 25 | + echo "firebase-ios-sdk SPM dependency.\n" |
| 26 | + echo "Usage: $0 <path_to.xcodeproj> [--version <version> | --revision <revision> | --prerelease | --branch <branch>]" |
| 27 | + exit 1 |
32 | 28 | fi
|
33 | 29 |
|
34 | 30 | XCODEPROJ_PATH="$1"
|
35 | 31 | shift
|
36 | 32 | MODE="$1"
|
37 | 33 | shift
|
38 | 34 |
|
39 |
| -# Validate Xcode project path |
40 |
| -if [[ ! -d "$XCODEPROJ_PATH" || ! "$XCODEPROJ_PATH" == *.xcodeproj ]]; then |
41 |
| - echo "Error: Invalid Xcode project path provided: $XCODEPROJ_PATH" |
42 |
| - exit 1 |
43 |
| -fi |
44 | 35 | PBXPROJ_PATH="${XCODEPROJ_PATH}/project.pbxproj"
|
45 |
| -if [[ ! -f "$PBXPROJ_PATH" ]]; then |
46 |
| - echo "Error: project.pbxproj not found at ${PBXPROJ_PATH}" |
47 |
| - exit 1 |
48 |
| -fi |
49 | 36 |
|
| 37 | +# Regex matches SemVer `firebase-ios-sdk` dependency in project.pbxproj: |
| 38 | +# { |
| 39 | +# isa = XCRemoteSwiftPackageReference; |
| 40 | +# repositoryURL = "https://github.com/firebase/firebase-ios-sdk.git"; |
| 41 | +# requirement = { |
| 42 | +# kind = upToNextMajorVersion; |
| 43 | +# minimumVersion = xx.yy.zz; |
| 44 | +# }; |
| 45 | +# }; |
| 46 | +REQUIREMENT_REGEX='({'\ |
| 47 | +'\s*isa = XCRemoteSwiftPackageReference;'\ |
| 48 | +'\s*repositoryURL = "https://github\.com/firebase/firebase-ios-sdk(?:\.git)?";'\ |
| 49 | +'\s*requirement = {\s*)kind = upToNextMajorVersion;'\ |
| 50 | +'\s*minimumVersion = \d+\.\d+\.\d+;'\ |
| 51 | +'(\s*};'\ |
| 52 | +'\s*};)' |
| 53 | + |
| 54 | +# Define the replacement regex based on the selected mode. |
50 | 55 | case "$MODE" in
|
51 | 56 | --version)
|
52 |
| - if [[ $# -lt 1 ]]; then usage; fi |
| 57 | + if [[ $# -lt 1 ]]; then echo "Error: Missing version for --version"; exit 1; fi |
53 | 58 | VERSION="$1"
|
54 |
| - # Release testing: Point to CocoaPods-{VERSION} tag (as a branch) |
55 |
| - export REPLACEMENT_VALUE |
56 |
| - REPLACEMENT_VALUE=$(printf '{\n\t\t\t\tkind = branch;\n\t\t\t\tbranch = "%s";\n\t\t\t}' "$VERSION") |
| 59 | + REPLACEMENT_REGEX="\1kind = branch;\n\t\t\t\tbranch = \"$VERSION\";\2" |
57 | 60 | ;;
|
58 | 61 | --prerelease)
|
59 |
| - # Prerelease testing: Point to the tip of the main branch |
60 | 62 | COMMIT_HASH=$(git ls-remote https://github.com/firebase/firebase-ios-sdk.git main | cut -f1)
|
61 | 63 | if [[ -z "$COMMIT_HASH" ]]; then
|
62 | 64 | echo "Error: Failed to get remote revision for main branch."
|
63 | 65 | exit 1
|
64 | 66 | fi
|
65 |
| - export REPLACEMENT_VALUE |
66 |
| - REPLACEMENT_VALUE=$(printf '{\n\t\t\t\tkind = revision;\n\t\t\t\trevision = "%s";\n\t\t\t}' "$COMMIT_HASH") |
| 67 | + REPLACEMENT_REGEX="\1kind = revision;\n\t\t\t\trevision = \"$COMMIT_HASH\";\2" |
67 | 68 | ;;
|
68 | 69 | --revision)
|
69 |
| - if [[ $# -lt 1 ]]; then usage; fi |
| 70 | + if [[ $# -lt 1 ]]; then echo "Error: Missing revision for --revision"; exit 1; fi |
70 | 71 | REVISION="$1"
|
71 |
| - # PR testing: Point to the specific commit hash of the current branch |
72 |
| - export REPLACEMENT_VALUE |
73 |
| - REPLACEMENT_VALUE=$(printf '{\n\t\t\t\tkind = revision;\n\t\t\t\trevision = "%s";\n\t\t\t}' "$REVISION") |
| 72 | + REPLACEMENT_REGEX="\1kind = revision;\n\t\t\t\trevision = \"$REVISION\";\2" |
| 73 | + ;; |
| 74 | + --branch) |
| 75 | + if [[ $# -lt 1 ]]; then echo "Error: Missing branch name for --branch"; exit 1; fi |
| 76 | + BRANCH_NAME="$1" |
| 77 | + REPLACEMENT_REGEX="\1kind = branch;\n\t\t\t\tbranch = \"$BRANCH_NAME\";\2" |
74 | 78 | ;;
|
75 | 79 | *)
|
76 |
| - usage |
| 80 | + echo "Invalid mode: $MODE" |
| 81 | + exit 1 |
77 | 82 | ;;
|
78 | 83 | esac
|
79 | 84 |
|
80 |
| -# Read the original content to check for changes later. |
81 |
| -ORIGINAL_CONTENT=$(<"$PBXPROJ_PATH") |
| 85 | +# Make a temporary backup of the original file. |
| 86 | +# This will be used to check if any changes were made. |
| 87 | +TEMP_FILE=$(mktemp) |
| 88 | +cp "$PBXPROJ_PATH" "$TEMP_FILE" |
82 | 89 |
|
83 |
| -# Use perl to perform the replacement. |
84 |
| -# -0777: Slurp the whole file into one string. |
85 |
| -# -i: Edit in-place. |
86 |
| -# -p: Loop over the input. |
87 |
| -# -e: Execute the script. |
88 |
| -# The `e` flag in `s/.../.../ge` evaluates the replacement as a Perl expression. |
89 |
| -# This allows us to use an environment variable for the replacement string, |
90 |
| -# avoiding quoting issues with shell variables. |
91 |
| -perl -0777 -i -pe 's#(repositoryURL = "https://github.com/firebase/firebase-ios-sdk\.git";\s*requirement = )\{[^\}]+\};#$1 . $ENV{"REPLACEMENT_VALUE"} . ";"#ge' "$PBXPROJ_PATH" || { |
| 90 | +# Performs the replacement using Perl. |
| 91 | +# |
| 92 | +# -0777 Enables reading all input in one go (slurp), rather than line-by-line. |
| 93 | +# -p Causes Perl to loop through the input line by line. |
| 94 | +# -i Edits the file in place. |
| 95 | +# -e Provides the expression to execute. |
| 96 | +perl -0777 -i -pe "s#$REQUIREMENT_REGEX#$REPLACEMENT_REGEX#g" "$PBXPROJ_PATH" || { |
92 | 97 | echo "Failed to update the Xcode project's SPM dependency."
|
93 | 98 | exit 1
|
94 | 99 | }
|
95 | 100 |
|
96 |
| -# Verify that the file was changed. |
97 |
| -UPDATED_CONTENT=$(<"$PBXPROJ_PATH") |
98 |
| -if [[ "$ORIGINAL_CONTENT" == "$UPDATED_CONTENT" ]]; then |
| 101 | +# Silently compare the modified file with the temporary backup. |
| 102 | +# If they are the same, cmp will return 0 (success), and the 'if' block will run. |
| 103 | +if cmp -s "$PBXPROJ_PATH" "$TEMP_FILE"; then |
99 | 104 | echo "Failed to find and replace the firebase-ios-sdk dependency. Check the regex pattern and project file structure."
|
| 105 | + # Restore the original file from the backup |
| 106 | + mv "$TEMP_FILE" "$PBXPROJ_PATH" |
100 | 107 | exit 1
|
101 |
| -} |
| 108 | +fi |
102 | 109 |
|
103 | 110 | echo "Successfully updated SPM dependency in $PBXPROJ_PATH"
|
104 | 111 |
|
|
0 commit comments