Skip to content

Commit c47eef6

Browse files
committed
Add pr_changed_files script to detect if files changed in a PR
1 parent e1517df commit c47eef6

File tree

1 file changed

+124
-0
lines changed

1 file changed

+124
-0
lines changed

bin/pr_changed_files

+124
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
#!/bin/bash -eu
2+
3+
# This script checks if files are changed in a PR.
4+
#
5+
# Usage:
6+
# pr_changed_files # Check if any files changed
7+
# pr_changed_files --includes <file-patterns...> # Check if changes include files matching patterns
8+
# pr_changed_files --only-in <file-patterns...> # Check if changes are limited to given patterns
9+
#
10+
# Examples:
11+
# # Check if any files changed
12+
# pr_changed_files
13+
#
14+
# # Check if only documentation files changed
15+
# pr_changed_files --only-in "*.md" "docs/**"
16+
#
17+
# # Check if any Swift files changed
18+
# pr_changed_files --includes "*.swift"
19+
#
20+
# Returns:
21+
# Prints "true" if the condition is met, "false" otherwise
22+
# Always exits with code 0 to allow easy variable assignment
23+
24+
if [[ ! "${BUILDKITE_PULL_REQUEST:-invalid}" =~ ^[0-9]+$ ]]; then
25+
echo "Error: this tool can only be called from a Buildkite PR job" >&2
26+
exit 1
27+
fi
28+
29+
mode=""
30+
patterns=()
31+
32+
while [[ "$#" -gt 0 ]]; do
33+
case $1 in
34+
--only-in)
35+
if [[ -n "$mode" ]]; then
36+
echo "Error: cannot specify both --only-in and --includes" >&2
37+
exit 1
38+
fi
39+
mode="only-in"
40+
shift
41+
while [[ "$#" -gt 0 && "$1" != "--"* ]]; do
42+
patterns+=("$1")
43+
shift
44+
done
45+
;;
46+
--includes)
47+
if [[ -n "$mode" ]]; then
48+
echo "Error: cannot specify both --only-in and --includes" >&2
49+
exit 1
50+
fi
51+
mode="includes"
52+
shift
53+
while [[ "$#" -gt 0 && "$1" != "--"* ]]; do
54+
patterns+=("$1")
55+
shift
56+
done
57+
;;
58+
--*)
59+
echo "Error: unknown option $1" >&2
60+
exit 1
61+
;;
62+
*)
63+
echo "Error: unexpected argument $1" >&2
64+
exit 1
65+
;;
66+
esac
67+
done
68+
69+
# Get list of changed files
70+
changed_files=$(git --no-pager diff --name-only --merge-base "$BUILDKITE_PULL_REQUEST_BASE_BRANCH" HEAD | sort)
71+
72+
if [[ -z "$mode" ]]; then
73+
# No arguments = any change
74+
if [[ -n "$changed_files" ]]; then
75+
echo "true"
76+
else
77+
echo "false"
78+
fi
79+
exit 0
80+
fi
81+
82+
if [[ ${#patterns[@]} -eq 0 ]]; then
83+
echo "Error: must specify at least one file pattern" >&2
84+
exit 1
85+
fi
86+
87+
# No files changed
88+
if [[ -z "$changed_files" ]]; then
89+
if [[ "$mode" == "only-in" ]]; then
90+
echo "true"
91+
else
92+
echo "false"
93+
fi
94+
exit 0
95+
fi
96+
97+
if [[ "$mode" == "only-in" ]]; then
98+
# Check if all changed files match at least one pattern
99+
for file in $changed_files; do
100+
matches_any=false
101+
for pattern in "${patterns[@]}"; do
102+
if [[ "$file" == $pattern ]]; then
103+
matches_any=true
104+
break
105+
fi
106+
done
107+
if [[ "$matches_any" == "false" ]]; then
108+
echo "false"
109+
exit 0
110+
fi
111+
done
112+
echo "true"
113+
elif [[ "$mode" == "includes" ]]; then
114+
# Check if any changed file matches any pattern
115+
for file in $changed_files; do
116+
for pattern in "${patterns[@]}"; do
117+
if [[ "$file" == $pattern ]]; then
118+
echo "true"
119+
exit 0
120+
fi
121+
done
122+
done
123+
echo "false"
124+
fi

0 commit comments

Comments
 (0)