@@ -107,17 +107,43 @@ def iter_archive_contents(archive):
107107 raise RuntimeError ("Unsupported archive format" )
108108
109109
110+ import re
111+ from pathlib import PurePath
112+
110113def write_ziglang_wheel (out_dir , * , version , platform , archive ):
111114 contents = {}
112115 contents ['ziglang/__init__.py' ] = b''
113116
114117 license_files = {}
118+ found_license_files = set ()
119+ potential_extra_licenses = set ()
120+
121+ # A bunch of standard license file patterns. If a file matches any of
122+ # these, we need to add them to required_license_paths and metadata.
123+ license_patterns = [
124+ r'COPYING.*' ,
125+ r'COPYRIGHT.*' ,
126+ r'COPYLEFT.*' ,
127+ r'LICEN[CS]E.*' ,
128+ r'LICEN[CS]E-.*' ,
129+ r'LICEN[CS]E\..*' ,
130+ r'PATENTS.*' ,
131+ r'NOTICE.*' ,
132+ r'LEGAL.*' ,
133+ r'AUTHORS.*' ,
134+ r'RIGHT*' ,
135+ r'PERMISSION*' ,
136+ r'THIRD[-_]PARTY[-_]LICENSES?.*' ,
137+ r'EULA*' ,
138+ r'MIT*' ,
139+ r'GPL*' ,
140+ r'AGPL*' ,
141+ r'LGPL*' ,
142+ r'APACHE*' ,
143+ ]
144+ license_regex = re .compile ('|' .join (f'^{ pattern } $' for pattern in license_patterns ), re .IGNORECASE )
115145
116- # The paths to these licenses MUST match both the actual files
117- # in the Zig source tarballs and the License-File entries listed
118- # below in the metadata. These are not prefixed with "ziglang/"
119- # since these are the actual paths in the Zig source tarballs.
120- license_paths = [
146+ required_license_paths = [
121147 'LICENSE' ,
122148 'lib/libc/glibc/LICENSES' ,
123149 'lib/libc/mingw/COPYING' ,
@@ -126,29 +152,32 @@ def write_ziglang_wheel(out_dir, *, version, platform, archive):
126152 'lib/libc/wasi/LICENSE-APACHE' ,
127153 'lib/libc/wasi/LICENSE-APACHE-LLVM' ,
128154 'lib/libc/wasi/LICENSE-MIT' ,
155+ 'lib/libc/wasi/libc-bottom-half/cloudlibc/LICENSE' ,
156+ 'lib/libc/wasi/libc-top-half/musl/COPYRIGHT' ,
129157 'lib/libcxx/LICENSE.TXT' ,
130158 'lib/libcxxabi/LICENSE.TXT' ,
131- 'lib/libunwind/LICENSE.TXT'
159+ 'lib/libunwind/LICENSE.TXT' ,
132160 ]
133161
134- found_license_files = set ()
135-
136162 for entry_name , entry_mode , entry_data in iter_archive_contents (archive ):
137163 entry_name = '/' .join (entry_name .split ('/' )[1 :])
138164 if not entry_name :
139165 continue
140166 if entry_name .startswith ('doc/' ):
141167 continue
142168
169+ # Check for additional license-like files
170+ potential_license_filename = PurePath (entry_name ).name
171+ if license_regex .match (potential_license_filename ):
172+ potential_extra_licenses .add (entry_name )
173+
143174 zip_info = ZipInfo (f'ziglang/{ entry_name } ' )
144175 zip_info .external_attr = (entry_mode & 0xFFFF ) << 16
145176 contents [zip_info ] = entry_data
146177
147- # Store license files separately for the dist-info
148- # directory (PEP 639)
149- if entry_name in license_paths :
150- license_files [entry_name ] = entry_data # adding to license files
151- found_license_files .add (entry_name ) # tracking found licenses
178+ if entry_name in required_license_paths :
179+ license_files [entry_name ] = entry_data
180+ found_license_files .add (entry_name )
152181
153182 if entry_name .startswith ('zig' ):
154183 contents ['ziglang/__main__.py' ] = f'''\
@@ -160,14 +189,17 @@ def write_ziglang_wheel(out_dir, *, version, platform, archive):
160189 import subprocess; sys.exit(subprocess.call(argv))
161190''' .encode ('ascii' )
162191
163- # Check if any license files are missing and warn. This
164- # is useful to detect changes in the Zig archive structure
165- # around licenses that may require updating the metadata.
166- missing_licenses = set (license_paths ) - found_license_files
192+ # 1. Check for missing required licenses paths
193+ missing_licenses = set (required_license_paths ) - found_license_files
167194 if missing_licenses :
168- print (f"\033 [93mWarning: the following license files were not found in the Zig archive: { ', ' .join (sorted (missing_licenses ))} "
169- "\n This may indicate a change in Zig's license file structure or an error in the listing of license files and/or paths.\033 [0m"
170- )
195+ print (f"\033 [93mWarning: the following required license files were not found in the Zig archive: { ', ' .join (sorted (missing_licenses ))} "
196+ "\n This may indicate a change in Zig's license file structure or an error in the listing of license files and/or paths.\033 [0m" )
197+
198+ # 2. Check for potentially missing license files
199+ extra_licenses = potential_extra_licenses - set (required_license_paths )
200+ if extra_licenses :
201+ print (f"\033 [93mWarning: found additional potential license files in the Zig archive but not included in the metadata: { ', ' .join (sorted (extra_licenses ))} "
202+ "\n Please consider adding these to the license paths if they should be included.\033 [0m" )
171203
172204 with open ('README.pypi.md' ) as f :
173205 description = f .read ()
@@ -198,6 +230,8 @@ def write_ziglang_wheel(out_dir, *, version, platform, archive):
198230 ('License-File' , 'ziglang/lib/libc/wasi/LICENSE-APACHE' ),
199231 ('License-File' , 'ziglang/lib/libc/wasi/LICENSE-APACHE-LLVM' ),
200232 ('License-File' , 'ziglang/lib/libc/wasi/LICENSE-MIT' ),
233+ ('License-File' , 'ziglang/lib/libc/wasi/libc-bottom-half/cloudlibc/LICENSE' ),
234+ ('License-File' , 'ziglang/lib/libc/wasi/libc-top-half/musl/COPYRIGHT' ),
201235 ('License-File' , 'ziglang/lib/libcxx/LICENSE.TXT' ),
202236 ('License-File' , 'ziglang/lib/libcxxabi/LICENSE.TXT' ),
203237 ('License-File' , 'ziglang/lib/libunwind/LICENSE.TXT' ),
0 commit comments