2424# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2525# THE SOFTWARE.
2626
27+ import functools
28+ import multiprocessing
2729import os
2830import os .path
2931import platform
3032import pathlib
33+ import re
3134import requests
3235import semver
3336import shutil
3437import stat
3538import sys
3639import subprocess
3740import tempfile
41+ import platformdirs
42+
43+ @functools .cache
44+ def _git_version ():
45+ version_str = subprocess .check_output (["git" , "--version" ], encoding = "ascii" , errors = "replace" )
46+ version_str = re .search ("([0-9]\.*)*[0-9]" , version_str ).group (0 )
47+ return tuple (int (part ) for part in version_str .split ("." ))
48+
49+ def git_filter_arg ():
50+ clone_supports_filter = (
51+ False if "NO_USE_CLONE_FILTER" in os .environ else _git_version () >= (2 , 36 , 0 )
52+ )
53+
54+ if clone_supports_filter :
55+ return ["--filter=blob:none" ]
56+ else :
57+ return []
3858
3959from .munge import munge
4060
4161# pyproject.toml `py_modules` values that are incorrect. These should all have PRs filed!
4262# and should be removed when the fixed version is incorporated in its respective bundle.
4363
4464pyproject_py_modules_blocklist = set ((
45- # adafruit bundle
46- "adafruit_colorsys" ,
47-
4865 # community bundle
4966 "at24mac_eeprom" ,
50- "circuitpython_Candlesticks" ,
51- "CircuitPython_Color_Picker" ,
52- "CircuitPython_Equalizer" ,
53- "CircuitPython_Scales" ,
54- "circuitPython_Slider" ,
55- "circuitpython_uboxplot" ,
56- "P1AM" ,
5767 "p1am_200_helpers" ,
5868))
5969
6272else :
6373 from tomli import loads as load_toml
6474
75+ mpy_cross_path = platformdirs .user_cache_path ("circuitpython-build-tools" , ensure_exists = True )
76+
6577def load_pyproject_toml (lib_path : pathlib .Path ):
6678 try :
6779 return load_toml ((lib_path / "pyproject.toml" ) .read_text (encoding = "utf-8" ))
@@ -108,9 +120,14 @@ def version_string(path=None, *, valid_semver=False):
108120 version = commitish
109121 return version
110122
111- def mpy_cross (mpy_cross_filename , circuitpython_tag , quiet = False ):
123+ def mpy_cross (version , quiet = False ):
124+ circuitpython_tag = version ["tag" ]
125+ name = version ["name" ]
126+ ext = ".exe" * (os .name == "nt" )
127+ mpy_cross_filename = mpy_cross_path / f"mpy-cross-{ name } { ext } "
128+
112129 if os .path .isfile (mpy_cross_filename ):
113- return
130+ return mpy_cross_filename
114131
115132 # Try to pull from S3
116133 uname = platform .uname ()
@@ -138,7 +155,7 @@ def mpy_cross(mpy_cross_filename, circuitpython_tag, quiet=False):
138155 os .chmod (mpy_cross_filename , os .stat (mpy_cross_filename )[0 ] | stat .S_IXUSR )
139156 if not quiet :
140157 print (" FOUND" )
141- return
158+ return mpy_cross_filename
142159 except Exception as e :
143160 if not quiet :
144161 print (f" exception fetching from S3: { e } " )
@@ -151,26 +168,21 @@ def mpy_cross(mpy_cross_filename, circuitpython_tag, quiet=False):
151168 print (title )
152169 print ("=" * len (title ))
153170
154- os .makedirs ("build_deps/" , exist_ok = True )
155- if not os .path .isdir ("build_deps/circuitpython" ):
156- clone = subprocess .run ("git clone https://github.com/adafruit/circuitpython.git build_deps/circuitpython" , shell = True )
157- if clone .returncode != 0 :
158- sys .exit (clone .returncode )
159-
160- current_dir = os .getcwd ()
161- os .chdir ("build_deps/circuitpython" )
162- make = subprocess .run ("git fetch && git checkout {TAG} && git submodule update" .format (TAG = circuitpython_tag ), shell = True )
163- os .chdir ("tools" )
164- make = subprocess .run ("git submodule update --init ." , shell = True )
165- os .chdir ("../mpy-cross" )
166- make = subprocess .run ("make clean && make" , shell = True )
167- os .chdir (current_dir )
168-
169- if make .returncode != 0 :
170- print ("Failed to build mpy-cross from source... bailing out" )
171- sys .exit (make .returncode )
172-
173- shutil .copy ("build_deps/circuitpython/mpy-cross/mpy-cross" , mpy_cross_filename )
171+ build_dir = mpy_cross_path / f"build-circuitpython-{ circuitpython_tag } "
172+ if not os .path .isdir (build_dir ):
173+ subprocess .check_call (["git" , "clone" , * git_filter_arg (), "-b" , circuitpython_tag , "https://github.com/adafruit/circuitpython.git" , build_dir ])
174+
175+ subprocess .check_call (["git" , "submodule" , "update" , "--recursive" ], cwd = build_dir )
176+ subprocess .check_call ([sys .executable , "tools/ci_fetch_deps.py" , "mpy-cross" ], cwd = build_dir )
177+ subprocess .check_call (["make" , "clean" ], cwd = build_dir / "mpy-cross" )
178+ subprocess .check_call (["make" , f"-j{ multiprocessing .cpu_count ()} " ], cwd = build_dir / "mpy-cross" )
179+
180+ mpy_built = build_dir / f"mpy-cross/build/mpy-cross{ ext } "
181+ if not os .path .exists (mpy_built ):
182+ mpy_built = build_dir / f"mpy-cross/mpy-cross{ ext } "
183+
184+ shutil .copy (mpy_built , mpy_cross_filename )
185+ return mpy_cross_filename
174186
175187def get_package_info (library_path , package_folder_prefix ):
176188 lib_path = pathlib .Path (library_path )
0 commit comments