Skip to content

Commit 5d28bb4

Browse files
jimmodpgeorge
authored andcommitted
tools/manifestfile.py: Add support for external libraries.
This adds a `add_library(name, path)` method for use in manifest.py that allows registering an external path (e.g. to another repo) by name. This name can then be passed to `require("package", library="name")` to reference packages in that repo/library rather than micropython-lib. Within the external library, `require()` continues to work as normal (referencing micropython-lib) by default, but they can also specify the library name to require another package from that repo/library. Signed-off-by: Jim Mussared <jim.mussared@gmail.com>
1 parent 5552896 commit 5d28bb4

File tree

1 file changed

+43
-10
lines changed

1 file changed

+43
-10
lines changed

tools/manifestfile.py

Lines changed: 43 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ def __init__(self, mode, path_vars=None):
194194
self._visited = set()
195195
# Stack of metadata for each level.
196196
self._metadata = [ManifestPackageMetadata()]
197+
# Registered external libraries.
198+
self._libraries = {}
197199

198200
def _resolve_path(self, path):
199201
# Convert path to an absolute path, applying variable substitutions.
@@ -208,6 +210,7 @@ def _manifest_globals(self, kwargs):
208210
"metadata": self.metadata,
209211
"include": self.include,
210212
"require": self.require,
213+
"add_library": self.add_library,
211214
"package": self.package,
212215
"module": self.module,
213216
"options": IncludeOptions(**kwargs),
@@ -388,14 +391,25 @@ def include(self, manifest_path, is_require=False, **kwargs):
388391
if is_require:
389392
self._metadata.pop()
390393

391-
def require(self, name, version=None, unix_ffi=False, pypi=None, **kwargs):
394+
def _require_from_path(self, library_path, name, version, extra_kwargs):
395+
for root, dirnames, filenames in os.walk(library_path):
396+
if os.path.basename(root) == name and "manifest.py" in filenames:
397+
self.include(root, is_require=True, **extra_kwargs)
398+
return True
399+
return False
400+
401+
def require(self, name, version=None, unix_ffi=False, pypi=None, library=None, **kwargs):
392402
"""
393-
Require a module by name from micropython-lib.
403+
Require a package by name from micropython-lib.
394404
395405
Optionally specify unix_ffi=True to use a module from the unix-ffi directory.
396406
397407
Optionally specify pipy="package-name" to indicate that this should
398408
use the named package from PyPI when building for CPython.
409+
410+
Optionally specify library="name" to reference a package from a
411+
library that has been previously registered with add_library(). Otherwise
412+
micropython-lib will be used.
399413
"""
400414
self._metadata[-1].check_initialised(self._mode)
401415

@@ -406,27 +420,46 @@ def require(self, name, version=None, unix_ffi=False, pypi=None, **kwargs):
406420
self._pypi_dependencies.append(pypi)
407421
return
408422

409-
if self._path_vars["MPY_LIB_DIR"]:
423+
if library is not None:
424+
# Find package in external library.
425+
if library not in self._libraries:
426+
raise ValueError("Unknown library '{}' for require('{}').".format(library, name))
427+
library_path = self._libraries[library]
428+
# Search for {library_path}/**/{name}/manifest.py.
429+
if not self._require_from_path(library_path, name, version, kwargs):
430+
raise ValueError(
431+
"Package '{}' not found in external library '{}' ({}).".format(
432+
name, library, library_path
433+
)
434+
)
435+
elif self._path_vars["MPY_LIB_DIR"]:
436+
# Find package in micropython-lib, in one of the three top-level directories.
410437
lib_dirs = ["micropython", "python-stdlib", "python-ecosys"]
411438
if unix_ffi:
412-
# Search unix-ffi only if unix_ffi=True, and make unix-ffi modules
439+
# Additionally search unix-ffi only if unix_ffi=True, and make unix-ffi modules
413440
# take precedence.
414441
lib_dirs = ["unix-ffi"] + lib_dirs
415442

416443
for lib_dir in lib_dirs:
417444
# Search for {lib_dir}/**/{name}/manifest.py.
418-
for root, dirnames, filenames in os.walk(
419-
os.path.join(self._path_vars["MPY_LIB_DIR"], lib_dir)
445+
if self._require_from_path(
446+
os.path.join(self._path_vars["MPY_LIB_DIR"], lib_dir), name, version, kwargs
420447
):
421-
if os.path.basename(root) == name and "manifest.py" in filenames:
422-
self.include(root, is_require=True, **kwargs)
423-
return
448+
return
424449

425-
raise ValueError("Library not found in local micropython-lib: {}".format(name))
450+
raise ValueError("Package '{}' not found in local micropython-lib.".format(name))
426451
else:
427452
# TODO: HTTP request to obtain URLs from manifest.json.
428453
raise ValueError("micropython-lib not available for require('{}').", name)
429454

455+
def add_library(self, library, library_path):
456+
"""
457+
Register the path to an external named library.
458+
459+
This allows require("name", library="library") to find packages in that library.
460+
"""
461+
self._libraries[library] = self._resolve_path(library_path)
462+
430463
def package(self, package_path, files=None, base_path=".", opt=None):
431464
"""
432465
Define a package, optionally restricting to a set of files.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy