🌐 AI搜索 & 代理 主页
Skip to content

Commit 3a1844c

Browse files
fix: make license script portable and deterministic
Address review feedback: - Remove bash 4.0+ associative array requirement for macOS compatibility - Add cross-platform hash function (md5sum on Linux, md5 on macOS) - Ensure deterministic iteration order using sorted groups file - Add better error handling for failed go-licenses commands - Fix grammar: 'architecture(s)' -> 'architectures' - Add documentation for third-party/ being a union of all architectures - Use file-based state instead of associative arrays for portability
1 parent 87ea319 commit 3a1844c

File tree

4 files changed

+72
-47
lines changed

4 files changed

+72
-47
lines changed

script/licenses

Lines changed: 65 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
# 3. Creating an index at the top of each platform file
88
# 4. Copying all license files to third-party/
99
#
10+
# Note: third-party/ is a union of all license files across all architectures.
11+
# This means that license files for dependencies present in only some architectures
12+
# may still appear in third-party/. This is intentional and ensures compliance.
13+
#
1014
# Note: we ignore warnings because we want the command to succeed, however the output should be checked
1115
# for any new warnings, and potentially we may need to add license information.
1216
#
@@ -23,21 +27,34 @@ export TEMPDIR="$(mktemp -d)"
2327

2428
trap "rm -fr ${TEMPDIR}" EXIT
2529

26-
# Define platforms and their architectures
27-
declare -A PLATFORM_ARCHS
28-
PLATFORM_ARCHS["linux"]="amd64 arm64 386"
29-
PLATFORM_ARCHS["darwin"]="amd64 arm64"
30-
PLATFORM_ARCHS["windows"]="amd64 arm64 386"
30+
# Cross-platform hash function (works on both Linux and macOS)
31+
compute_hash() {
32+
if command -v md5sum >/dev/null 2>&1; then
33+
md5sum | cut -d' ' -f1
34+
elif command -v md5 >/dev/null 2>&1; then
35+
md5 -q
36+
else
37+
# Fallback to cksum if neither is available
38+
cksum | cut -d' ' -f1
39+
fi
40+
}
41+
42+
# Function to get architectures for a given OS
43+
get_archs() {
44+
case "$1" in
45+
linux) echo "386 amd64 arm64" ;;
46+
darwin) echo "amd64 arm64" ;;
47+
windows) echo "386 amd64 arm64" ;;
48+
esac
49+
}
3150

3251
# Generate reports for each platform/arch combination
33-
for goos in linux darwin windows; do
52+
for goos in darwin linux windows; do
3453
echo "Processing ${goos}..."
3554

36-
# Store reports per arch for this platform
37-
declare -A ARCH_REPORTS
38-
declare -A ARCH_HASHES
55+
archs=$(get_archs "$goos")
3956

40-
for goarch in ${PLATFORM_ARCHS[$goos]}; do
57+
for goarch in $archs; do
4158
echo " Generating for ${goos}/${goarch}..."
4259

4360
# Generate the license report for this arch
@@ -47,27 +64,42 @@ for goos in linux darwin windows; do
4764
# Save licenses to temp directory
4865
GOOS="${goos}" GOARCH="${goarch}" GOFLAGS=-mod=mod go-licenses save ./... --save_path="${TEMPDIR}/${goos}_${goarch}" --force 2>/dev/null || echo " (warnings ignored for ${goos}/${goarch})"
4966

50-
# Copy to third-party (accumulate all)
67+
# Copy to third-party (accumulate all - union of all architectures for compliance)
5168
if [ -d "${TEMPDIR}/${goos}_${goarch}" ]; then
5269
cp -fR "${TEMPDIR}/${goos}_${goarch}"/* third-party/ 2>/dev/null || true
5370
fi
5471

55-
# Extract just the package list (skip header) and hash it
56-
packages=$(grep -E '^ - \[' "${report_file}" 2>/dev/null | sort || echo "")
57-
hash=$(echo "${packages}" | md5sum | cut -d' ' -f1)
72+
# Extract just the package list (skip header), sort it, and hash it
73+
packages_file="${TEMPDIR}/${goos}_${goarch}_packages.txt"
74+
if [ -s "${report_file}" ] && grep -qE '^ - \[' "${report_file}" 2>/dev/null; then
75+
grep -E '^ - \[' "${report_file}" | sort > "${packages_file}"
76+
hash=$(cat "${packages_file}" | compute_hash)
77+
else
78+
echo "(FAILED TO GENERATE LICENSE REPORT FOR ${goos}/${goarch})" > "${packages_file}"
79+
hash="FAILED_${goos}_${goarch}"
80+
fi
5881

59-
ARCH_REPORTS["${goarch}"]="${packages}"
60-
ARCH_HASHES["${goarch}"]="${hash}"
82+
# Store hash for grouping
83+
echo "${hash}" > "${TEMPDIR}/${goos}_${goarch}_hash.txt"
6184
done
6285

63-
# Group architectures with identical reports
64-
declare -A HASH_TO_ARCHS
65-
for goarch in ${PLATFORM_ARCHS[$goos]}; do
66-
hash="${ARCH_HASHES[$goarch]}"
67-
if [ -n "${HASH_TO_ARCHS[$hash]}" ]; then
68-
HASH_TO_ARCHS["${hash}"]="${HASH_TO_ARCHS[$hash]}, ${goarch}"
86+
# Group architectures with identical reports (deterministic order)
87+
# Create groups file: hash -> comma-separated archs
88+
groups_file="${TEMPDIR}/${goos}_groups.txt"
89+
rm -f "${groups_file}"
90+
91+
# Process architectures in order to build groups
92+
for goarch in $archs; do
93+
hash=$(cat "${TEMPDIR}/${goos}_${goarch}_hash.txt")
94+
# Check if we've seen this hash before
95+
if grep -q "^${hash}:" "${groups_file}" 2>/dev/null; then
96+
# Append to existing group
97+
existing=$(grep "^${hash}:" "${groups_file}" | cut -d: -f2)
98+
sed -i.bak "s/^${hash}:.*/${hash}:${existing}, ${goarch}/" "${groups_file}"
99+
rm -f "${groups_file}.bak"
69100
else
70-
HASH_TO_ARCHS["${hash}"]="${goarch}"
101+
# New group
102+
echo "${hash}:${goarch}" >> "${groups_file}"
71103
fi
72104
done
73105

@@ -83,29 +115,27 @@ The following open source dependencies are used to build the [github/github-mcp-
83115
84116
EOF
85117

86-
# Build table of contents
87-
for hash in "${!HASH_TO_ARCHS[@]}"; do
88-
archs="${HASH_TO_ARCHS[$hash]}"
118+
# Build table of contents (sorted for determinism)
119+
sort "${groups_file}" | while IFS=: read -r hash group_archs; do
89120
# Create anchor-friendly name
90-
anchor=$(echo "${archs}" | tr ', ' '-' | tr -s '-')
91-
echo "- [${archs}](#${anchor})" >> "${output_file}"
121+
anchor=$(echo "${group_archs}" | tr ', ' '-' | tr -s '-')
122+
echo "- [${group_archs}](#${anchor})" >> "${output_file}"
92123
done
93124

94125
echo "" >> "${output_file}"
95126
echo "---" >> "${output_file}"
96127
echo "" >> "${output_file}"
97128

98-
# Add each unique report section
99-
for hash in "${!HASH_TO_ARCHS[@]}"; do
100-
archs="${HASH_TO_ARCHS[$hash]}"
129+
# Add each unique report section (sorted for determinism)
130+
sort "${groups_file}" | while IFS=: read -r hash group_archs; do
101131
# Get the packages from the first arch in this group
102-
first_arch=$(echo "${archs}" | cut -d',' -f1 | tr -d ' ')
103-
packages="${ARCH_REPORTS[$first_arch]}"
132+
first_arch=$(echo "${group_archs}" | cut -d',' -f1 | tr -d ' ')
133+
packages=$(cat "${TEMPDIR}/${goos}_${first_arch}_packages.txt")
104134

105135
cat >> "${output_file}" << EOF
106-
## ${archs}
136+
## ${group_archs}
107137
108-
The following packages are included for the ${archs} architecture(s).
138+
The following packages are included for the ${group_archs} architectures.
109139
110140
${packages}
111141
@@ -116,11 +146,6 @@ EOF
116146
echo "[github/github-mcp-server]: https://github.com/github/github-mcp-server" >> "${output_file}"
117147

118148
echo "Generated ${output_file}"
119-
120-
# Clean up associative arrays for next platform
121-
unset ARCH_REPORTS
122-
unset ARCH_HASHES
123-
unset HASH_TO_ARCHS
124149
done
125150

126151
echo "Done! License files generated."

third-party-licenses.darwin.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ The following open source dependencies are used to build the [github/github-mcp-
1010

1111
## amd64, arm64
1212

13-
The following packages are included for the amd64, arm64 architecture(s).
13+
The following packages are included for the amd64, arm64 architectures.
1414

1515
- [github.com/aymerick/douceur](https://pkg.go.dev/github.com/aymerick/douceur) ([MIT](https://github.com/aymerick/douceur/blob/v0.2.0/LICENSE))
1616
- [github.com/fsnotify/fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify) ([BSD-3-Clause](https://github.com/fsnotify/fsnotify/blob/v1.9.0/LICENSE))

third-party-licenses.linux.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ The following open source dependencies are used to build the [github/github-mcp-
44

55
## Table of Contents
66

7-
- [amd64, arm64, 386](#amd64-arm64-386)
7+
- [386, amd64, arm64](#386-amd64-arm64)
88

99
---
1010

11-
## amd64, arm64, 386
11+
## 386, amd64, arm64
1212

13-
The following packages are included for the amd64, arm64, 386 architecture(s).
13+
The following packages are included for the 386, amd64, arm64 architectures.
1414

1515
- [github.com/aymerick/douceur](https://pkg.go.dev/github.com/aymerick/douceur) ([MIT](https://github.com/aymerick/douceur/blob/v0.2.0/LICENSE))
1616
- [github.com/fsnotify/fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify) ([BSD-3-Clause](https://github.com/fsnotify/fsnotify/blob/v1.9.0/LICENSE))

third-party-licenses.windows.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ The following open source dependencies are used to build the [github/github-mcp-
44

55
## Table of Contents
66

7-
- [amd64, arm64, 386](#amd64-arm64-386)
7+
- [386, amd64, arm64](#386-amd64-arm64)
88

99
---
1010

11-
## amd64, arm64, 386
11+
## 386, amd64, arm64
1212

13-
The following packages are included for the amd64, arm64, 386 architecture(s).
13+
The following packages are included for the 386, amd64, arm64 architectures.
1414

1515
- [github.com/aymerick/douceur](https://pkg.go.dev/github.com/aymerick/douceur) ([MIT](https://github.com/aymerick/douceur/blob/v0.2.0/LICENSE))
1616
- [github.com/fsnotify/fsnotify](https://pkg.go.dev/github.com/fsnotify/fsnotify) ([BSD-3-Clause](https://github.com/fsnotify/fsnotify/blob/v1.9.0/LICENSE))

0 commit comments

Comments
 (0)