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
2428trap " 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
84116EOF
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
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
124149done
125150
126151echo " Done! License files generated."
0 commit comments