4040import tempfile
4141import platformdirs
4242
43+
4344@functools .cache
4445def _git_version ():
4546 version_str = subprocess .check_output (["git" , "--version" ], encoding = "ascii" , errors = "replace" )
4647 version_str = re .search (r"([0-9]\.*)*[0-9]" , version_str ).group (0 )
4748 return tuple (int (part ) for part in version_str .split ("." ))
4849
50+
4951def git_filter_arg ():
5052 clone_supports_filter = (
5153 False if "NO_USE_CLONE_FILTER" in os .environ else _git_version () >= (2 , 36 , 0 )
@@ -56,14 +58,17 @@ def git_filter_arg():
5658 else :
5759 return []
5860
61+
5962# pyproject.toml `py_modules` values that are incorrect. These should all have PRs filed!
6063# and should be removed when the fixed version is incorporated in its respective bundle.
6164
62- pyproject_py_modules_blocklist = set ((
63- # community bundle
64- "at24mac_eeprom" ,
65- "p1am_200_helpers" ,
66- ))
65+ pyproject_py_modules_blocklist = set (
66+ (
67+ # community bundle
68+ "at24mac_eeprom" ,
69+ "p1am_200_helpers" ,
70+ )
71+ )
6772
6873if sys .version_info >= (3 , 11 ):
6974 from tomllib import loads as load_toml
@@ -72,52 +77,70 @@ def git_filter_arg():
7277
7378mpy_cross_path = platformdirs .user_cache_path ("circuitpython-build-tools" , ensure_exists = True )
7479
80+
7581def load_pyproject_toml (lib_path : pathlib .Path ):
7682 try :
77- return load_toml ((lib_path / "pyproject.toml" ) .read_text (encoding = "utf-8" ))
83+ return load_toml ((lib_path / "pyproject.toml" ).read_text (encoding = "utf-8" ))
7884 except FileNotFoundError :
7985 print (f"No pyproject.toml in { lib_path } " )
8086 return {}
8187
88+
8289def get_nested (doc , * args , default = None ):
8390 for a in args :
84- if doc is None : return default
91+ if doc is None :
92+ return default
8593 try :
8694 doc = doc [a ]
8795 except (KeyError , IndexError ):
8896 return default
8997 return doc
9098
99+
91100IGNORE_PY = ["setup.py" , "conf.py" , "__init__.py" ]
92101GLOB_PATTERNS = ["*.py" , "*.bin" ]
93102S3_MPY_PREFIX = "https://adafruit-circuit-python.s3.amazonaws.com/bin/mpy-cross"
94103
104+
95105def version_string (path = None , * , valid_semver = False ):
96106 version = None
97- tag = subprocess .run ('git describe --tags --exact-match' , shell = True , stdout = subprocess .PIPE , stderr = subprocess .PIPE , cwd = path )
107+ tag = subprocess .run (
108+ "git describe --tags --exact-match" ,
109+ shell = True ,
110+ stdout = subprocess .PIPE ,
111+ stderr = subprocess .PIPE ,
112+ cwd = path ,
113+ )
98114 if tag .returncode == 0 :
99115 version = tag .stdout .strip ().decode ("utf-8" , "strict" )
100116 else :
101- describe = subprocess .run ("git describe --tags --always" , shell = True , stdout = subprocess .PIPE , cwd = path )
117+ describe = subprocess .run (
118+ "git describe --tags --always" , shell = True , stdout = subprocess .PIPE , cwd = path
119+ )
102120 describe = describe .stdout .strip ().decode ("utf-8" , "strict" ).rsplit ("-" , maxsplit = 2 )
103121 if len (describe ) == 3 :
104122 tag , additional_commits , commitish = describe
105123 commitish = commitish [1 :]
106124 else :
107125 tag = "0.0.0"
108- commit_count = subprocess .run ("git rev-list --count HEAD" , shell = True , stdout = subprocess .PIPE , cwd = path )
126+ commit_count = subprocess .run (
127+ "git rev-list --count HEAD" , shell = True , stdout = subprocess .PIPE , cwd = path
128+ )
109129 additional_commits = commit_count .stdout .strip ().decode ("utf-8" , "strict" )
110130 commitish = describe [0 ]
111131 if valid_semver :
112132 version_info = semver .parse_version_info (tag )
113133 if not version_info .prerelease :
114- version = semver .bump_patch (tag ) + "-alpha.0.plus." + additional_commits + "+" + commitish
134+ version = (
135+ semver .bump_patch (tag ) + "-alpha.0.plus." + additional_commits + "+" + commitish
136+ )
115137 else :
116138 version = tag + ".plus." + additional_commits + "+" + commitish
117139 else :
118140 version = commitish
119141 return version
120142
143+
121144def mpy_cross (version , quiet = False ):
122145 circuitpython_tag = version ["tag" ]
123146 name = version ["name" ]
@@ -130,16 +153,18 @@ def mpy_cross(version, quiet=False):
130153 # Try to pull from S3
131154 uname = platform .uname ()
132155 s3_url = None
133- if uname [0 ].title () == ' Linux' and uname [4 ].lower () in (' amd64' , ' x86_64' ):
156+ if uname [0 ].title () == " Linux" and uname [4 ].lower () in (" amd64" , " x86_64" ):
134157 s3_url = f"{ S3_MPY_PREFIX } /linux-amd64/mpy-cross-linux-amd64-{ circuitpython_tag } .static"
135- elif uname [0 ].title () == ' Linux' and uname [4 ].lower () == ' armv7l' :
158+ elif uname [0 ].title () == " Linux" and uname [4 ].lower () == " armv7l" :
136159 s3_url = f"{ S3_MPY_PREFIX } /linux-raspbian/mpy-cross-linux-raspbian-{ circuitpython_tag } .static-raspbian"
137- elif uname [0 ].title () == ' Darwin' :
160+ elif uname [0 ].title () == " Darwin" :
138161 s3_url = f"{ S3_MPY_PREFIX } /macos/mpy-cross-macos-{ circuitpython_tag } -universal"
139162 elif uname [0 ].title () == "Windows" and uname [4 ].lower () in ("amd64" , "x86_64" ):
140163 s3_url = f"{ S3_MPY_PREFIX } /windows/mpy-cross-windows-{ circuitpython_tag } .static.exe"
141164 elif not quiet :
142- print (f"Pre-built mpy-cross not available for sysname='{ uname [0 ]} ' release='{ uname [2 ]} ' machine='{ uname [4 ]} '." )
165+ print (
166+ f"Pre-built mpy-cross not available for sysname='{ uname [0 ]} ' release='{ uname [2 ]} ' machine='{ uname [4 ]} '."
167+ )
143168
144169 if s3_url is not None :
145170 if not quiet :
@@ -168,7 +193,17 @@ def mpy_cross(version, quiet=False):
168193
169194 build_dir = mpy_cross_path / f"build-circuitpython-{ circuitpython_tag } "
170195 if not os .path .isdir (build_dir ):
171- subprocess .check_call (["git" , "clone" , * git_filter_arg (), "-b" , circuitpython_tag , "https://github.com/adafruit/circuitpython.git" , build_dir ])
196+ subprocess .check_call (
197+ [
198+ "git" ,
199+ "clone" ,
200+ * git_filter_arg (),
201+ "-b" ,
202+ circuitpython_tag ,
203+ "https://github.com/adafruit/circuitpython.git" ,
204+ build_dir ,
205+ ]
206+ )
172207
173208 subprocess .check_call (["git" , "submodule" , "update" , "--recursive" ], cwd = build_dir )
174209 subprocess .check_call ([sys .executable , "tools/ci_fetch_deps.py" , "mpy-cross" ], cwd = build_dir )
@@ -182,6 +217,7 @@ def mpy_cross(version, quiet=False):
182217 shutil .copy (mpy_built , mpy_cross_filename )
183218 return mpy_cross_filename
184219
220+
185221def _munge_to_temp (original_path , temp_file , library_version ):
186222 with open (original_path , "r" , encoding = "utf-8" ) as original_file :
187223 for line in original_file :
@@ -192,6 +228,7 @@ def _munge_to_temp(original_path, temp_file, library_version):
192228 print (line , file = temp_file )
193229 temp_file .flush ()
194230
231+
195232def get_package_info (library_path , package_folder_prefix ):
196233 lib_path = pathlib .Path (library_path )
197234 parent_idx = len (lib_path .parts )
@@ -210,11 +247,14 @@ def get_package_info(library_path, package_folder_prefix):
210247 blocklisted = [name for name in py_modules if name in pyproject_py_modules_blocklist ]
211248
212249 if blocklisted :
213- print (f"{ lib_path } /settings.toml:1: { blocklisted [0 ]} blocklisted: not using metadata from pyproject.toml" )
250+ print (
251+ f"{ lib_path } /settings.toml:1: { blocklisted [0 ]} blocklisted: not using metadata from pyproject.toml"
252+ )
214253 py_modules = packages = ()
215254
216- example_files = [sub_path for sub_path in (lib_path / "examples" ).rglob ("*" )
217- if sub_path .is_file ()]
255+ example_files = [
256+ sub_path for sub_path in (lib_path / "examples" ).rglob ("*" ) if sub_path .is_file ()
257+ ]
218258
219259 if packages and py_modules :
220260 raise ValueError ("Cannot specify both tool.setuptools.py-modules and .packages" )
@@ -223,17 +263,18 @@ def get_package_info(library_path, package_folder_prefix):
223263 if len (packages ) > 1 :
224264 raise ValueError ("Only a single package is supported" )
225265 package_name = packages [0 ]
226- #print(f"Using package name from pyproject.toml: {package_name}")
266+ # print(f"Using package name from pyproject.toml: {package_name}")
227267 package_info ["is_package" ] = True
228268 package_info ["module_name" ] = package_name
229- package_files = [sub_path for sub_path in (lib_path / package_name ).rglob ("*" )
230- if sub_path .is_file ()]
269+ package_files = [
270+ sub_path for sub_path in (lib_path / package_name ).rglob ("*" ) if sub_path .is_file ()
271+ ]
231272
232273 elif py_modules :
233274 if len (py_modules ) > 1 :
234275 raise ValueError ("Only a single module is supported" )
235276 py_module = py_modules [0 ]
236- #print(f"Using module name from pyproject.toml: {py_module}")
277+ # print(f"Using module name from pyproject.toml: {py_module}")
237278 package_name = py_module
238279 package_info ["is_package" ] = False
239280 package_info ["module_name" ] = py_module
@@ -252,7 +293,7 @@ def get_package_info(library_path, package_folder_prefix):
252293 package_files .append (file )
253294 else :
254295 if file .name in IGNORE_PY :
255- #print("Ignoring:", file.resolve())
296+ # print("Ignoring:", file.resolve())
256297 continue
257298 if file .parent == lib_path :
258299 py_files .append (file )
@@ -265,8 +306,10 @@ def get_package_info(library_path, package_folder_prefix):
265306 package_info ["module_name" ] = None
266307
267308 if len (py_files ) > 1 :
268- raise ValueError ("Multiple top level py files not allowed. Please put "
269- "them in a package or combine them into a single file." )
309+ raise ValueError (
310+ "Multiple top level py files not allowed. Please put "
311+ "them in a package or combine them into a single file."
312+ )
270313
271314 package_info ["package_files" ] = package_files
272315 package_info ["py_files" ] = py_files
@@ -281,21 +324,22 @@ def get_package_info(library_path, package_folder_prefix):
281324
282325 return package_info
283326
284- def library (library_path , output_directory , package_folder_prefix ,
285- mpy_cross = None , example_bundle = False ):
327+
328+ def library (
329+ library_path , output_directory , package_folder_prefix , mpy_cross = None , example_bundle = False
330+ ):
286331 lib_path = pathlib .Path (library_path )
287332 package_info = get_package_info (library_path , package_folder_prefix )
288333 py_package_files = package_info ["package_files" ] + package_info ["py_files" ]
289334 example_files = package_info ["example_files" ]
290335 module_name = package_info ["module_name" ]
291336
292337 for fn in py_package_files :
293- base_dir = os .path .join (output_directory ,
294- fn .relative_to (library_path ).parent )
338+ base_dir = os .path .join (output_directory , fn .relative_to (library_path ).parent )
295339 if not os .path .isdir (base_dir ):
296340 os .makedirs (base_dir )
297341
298- library_version = package_info [' version' ]
342+ library_version = package_info [" version" ]
299343
300344 if not example_bundle :
301345 for filename in py_package_files :
@@ -309,12 +353,16 @@ def library(library_path, output_directory, package_folder_prefix,
309353 temp_file .close ()
310354 if mpy_cross and os .stat (temp_file .name ).st_size != 0 :
311355 output_file = output_file .with_suffix (".mpy" )
312- mpy_success = subprocess .call ([
313- mpy_cross ,
314- "-o" , output_file ,
315- "-s" , str (filename .relative_to (library_path )),
316- temp_file .name
317- ])
356+ mpy_success = subprocess .call (
357+ [
358+ mpy_cross ,
359+ "-o" ,
360+ output_file ,
361+ "-s" ,
362+ str (filename .relative_to (library_path )),
363+ temp_file .name ,
364+ ]
365+ )
318366 if mpy_success != 0 :
319367 raise RuntimeError ("mpy-cross failed on" , full_path )
320368 else :
@@ -349,8 +397,7 @@ def library(library_path, output_directory, package_folder_prefix,
349397 relative_filename_parts = list (filename .relative_to (library_path ).parts )
350398 relative_filename_parts .insert (1 , library_path .split (os .path .sep )[- 1 ])
351399 final_relative_filename = os .path .join (* relative_filename_parts )
352- output_file = os .path .join (output_directory .replace ("/lib" , "/" ),
353- final_relative_filename )
400+ output_file = os .path .join (output_directory .replace ("/lib" , "/" ), final_relative_filename )
354401
355402 os .makedirs (os .path .join (* output_file .split (os .path .sep )[:- 1 ]), exist_ok = True )
356403 shutil .copyfile (full_path , output_file )
0 commit comments