moving class definitions to own files
This commit is contained in:
parent
2572c32afe
commit
a2ae043684
3 changed files with 202 additions and 193 deletions
0
circup/bundle.py
Normal file
0
circup/bundle.py
Normal file
|
|
@ -150,196 +150,3 @@ class Bundle:
|
|||
)
|
||||
|
||||
|
||||
class Module:
|
||||
"""
|
||||
Represents a CircuitPython module.
|
||||
"""
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
backend,
|
||||
repo,
|
||||
device_version,
|
||||
bundle_version,
|
||||
mpy,
|
||||
bundle,
|
||||
compatibility,
|
||||
):
|
||||
"""
|
||||
The ``self.file`` and ``self.name`` attributes are constructed from
|
||||
the ``path`` value. If the path is to a directory based module, the
|
||||
resulting self.file value will be None, and the name will be the
|
||||
basename of the directory path.
|
||||
|
||||
:param str name: The file name of the module.
|
||||
:param Backend backend: The backend that the module is on.
|
||||
:param str repo: The URL of the Git repository for this module.
|
||||
:param str device_version: The semver value for the version on device.
|
||||
:param str bundle_version: The semver value for the version in bundle.
|
||||
:param bool mpy: Flag to indicate if the module is byte-code compiled.
|
||||
:param Bundle bundle: Bundle object where the module is located.
|
||||
:param (str,str) compatibility: Min and max versions of CP compatible with the mpy.
|
||||
"""
|
||||
self.name = name
|
||||
self.backend = backend
|
||||
self.path = (
|
||||
urljoin(backend.library_path, name, allow_fragments=False)
|
||||
if isinstance(backend, WebBackend)
|
||||
else os.path.join(backend.library_path, name)
|
||||
)
|
||||
|
||||
url = urlparse(self.path, allow_fragments=False)
|
||||
|
||||
if (
|
||||
url.path.endswith("/")
|
||||
if isinstance(backend, WebBackend)
|
||||
else self.path.endswith(os.sep)
|
||||
):
|
||||
self.file = None
|
||||
self.name = self.path.split(
|
||||
"/" if isinstance(backend, WebBackend) else os.sep
|
||||
)[-2]
|
||||
else:
|
||||
self.file = os.path.basename(url.path)
|
||||
self.name = (
|
||||
os.path.basename(url.path).replace(".py", "").replace(".mpy", "")
|
||||
)
|
||||
|
||||
self.repo = repo
|
||||
self.device_version = device_version
|
||||
self.bundle_version = bundle_version
|
||||
self.mpy = mpy
|
||||
self.min_version = compatibility[0]
|
||||
self.max_version = compatibility[1]
|
||||
# Figure out the bundle path.
|
||||
self.bundle_path = None
|
||||
if self.mpy:
|
||||
# Byte compiled, now check CircuitPython version.
|
||||
major_version = CPY_VERSION.split(".")[0]
|
||||
bundle_platform = "{}mpy".format(major_version)
|
||||
else:
|
||||
# Regular Python
|
||||
bundle_platform = "py"
|
||||
# module path in the bundle
|
||||
search_path = bundle.lib_dir(bundle_platform)
|
||||
if self.file:
|
||||
self.bundle_path = os.path.join(search_path, self.file)
|
||||
else:
|
||||
self.bundle_path = os.path.join(search_path, self.name)
|
||||
logger.info(self)
|
||||
|
||||
# pylint: enable=too-many-arguments
|
||||
|
||||
@property
|
||||
def outofdate(self):
|
||||
"""
|
||||
Returns a boolean to indicate if this module is out of date.
|
||||
Treat mismatched MPY versions as out of date.
|
||||
|
||||
:return: Truthy indication if the module is out of date.
|
||||
"""
|
||||
if self.mpy_mismatch:
|
||||
return True
|
||||
if self.device_version and self.bundle_version:
|
||||
try:
|
||||
return VersionInfo.parse(self.device_version) < VersionInfo.parse(
|
||||
self.bundle_version
|
||||
)
|
||||
except ValueError as ex:
|
||||
logger.warning("Module '%s' has incorrect semver value.", self.name)
|
||||
logger.warning(ex)
|
||||
return True # Assume out of date to try to update.
|
||||
|
||||
@property
|
||||
def bad_format(self):
|
||||
"""A boolean indicating that the mpy file format could not be identified"""
|
||||
return self.mpy and self.device_version == BAD_FILE_FORMAT
|
||||
|
||||
@property
|
||||
def mpy_mismatch(self):
|
||||
"""
|
||||
Returns a boolean to indicate if this module's MPY version is compatible
|
||||
with the board's current version of Circuitpython. A min or max version
|
||||
that evals to False means no limit.
|
||||
|
||||
:return: Boolean indicating if the MPY versions don't match.
|
||||
"""
|
||||
if not self.mpy:
|
||||
return False
|
||||
try:
|
||||
cpv = VersionInfo.parse(CPY_VERSION)
|
||||
except ValueError as ex:
|
||||
logger.warning("CircuitPython has incorrect semver value.")
|
||||
logger.warning(ex)
|
||||
try:
|
||||
if self.min_version and cpv < VersionInfo.parse(self.min_version):
|
||||
return True # CP version too old
|
||||
if self.max_version and cpv >= VersionInfo.parse(self.max_version):
|
||||
return True # MPY version too old
|
||||
except (TypeError, ValueError) as ex:
|
||||
logger.warning(
|
||||
"Module '%s' has incorrect MPY compatibility information.", self.name
|
||||
)
|
||||
logger.warning(ex)
|
||||
return False
|
||||
|
||||
@property
|
||||
def major_update(self):
|
||||
"""
|
||||
Returns a boolean to indicate if this is a major version update.
|
||||
|
||||
:return: Boolean indicating if this is a major version upgrade
|
||||
"""
|
||||
try:
|
||||
if (
|
||||
VersionInfo.parse(self.device_version).major
|
||||
== VersionInfo.parse(self.bundle_version).major
|
||||
):
|
||||
return False
|
||||
except (TypeError, ValueError) as ex:
|
||||
logger.warning("Module '%s' has incorrect semver value.", self.name)
|
||||
logger.warning(ex)
|
||||
return True # Assume Major Version udpate.
|
||||
|
||||
@property
|
||||
def row(self):
|
||||
"""
|
||||
Returns a tuple of items to display in a table row to show the module's
|
||||
name, local version and remote version, and reason to update.
|
||||
|
||||
:return: A tuple containing the module's name, version on the connected
|
||||
device, version in the latest bundle and reason to update.
|
||||
"""
|
||||
loc = self.device_version if self.device_version else "unknown"
|
||||
rem = self.bundle_version if self.bundle_version else "unknown"
|
||||
if self.mpy_mismatch:
|
||||
update_reason = "MPY Format"
|
||||
elif self.major_update:
|
||||
update_reason = "Major Version"
|
||||
else:
|
||||
update_reason = "Minor Version"
|
||||
return (self.name, loc, rem, update_reason)
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
Helps with log files.
|
||||
|
||||
:return: A repr of a dictionary containing the module's metadata.
|
||||
"""
|
||||
return repr(
|
||||
{
|
||||
"path": self.path,
|
||||
"file": self.file,
|
||||
"name": self.name,
|
||||
"repo": self.repo,
|
||||
"device_version": self.device_version,
|
||||
"bundle_version": self.bundle_version,
|
||||
"bundle_path": self.bundle_path,
|
||||
"mpy": self.mpy,
|
||||
"min_version": self.min_version,
|
||||
"max_version": self.max_version,
|
||||
}
|
||||
)
|
||||
|
|
|
|||
202
circup/module.py
Normal file
202
circup/module.py
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
import os
|
||||
from urllib.parse import urljoin, urlparse
|
||||
from semver import VersionInfo
|
||||
|
||||
from circup.shared import BAD_FILE_FORMAT, \
|
||||
from circup.backends import WebBackend
|
||||
from circup.logging import logger
|
||||
|
||||
class Module:
|
||||
"""
|
||||
Represents a CircuitPython module.
|
||||
"""
|
||||
|
||||
# pylint: disable=too-many-arguments
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
name,
|
||||
backend,
|
||||
repo,
|
||||
device_version,
|
||||
bundle_version,
|
||||
mpy,
|
||||
bundle,
|
||||
compatibility,
|
||||
):
|
||||
"""
|
||||
The ``self.file`` and ``self.name`` attributes are constructed from
|
||||
the ``path`` value. If the path is to a directory based module, the
|
||||
resulting self.file value will be None, and the name will be the
|
||||
basename of the directory path.
|
||||
|
||||
:param str name: The file name of the module.
|
||||
:param Backend backend: The backend that the module is on.
|
||||
:param str repo: The URL of the Git repository for this module.
|
||||
:param str device_version: The semver value for the version on device.
|
||||
:param str bundle_version: The semver value for the version in bundle.
|
||||
:param bool mpy: Flag to indicate if the module is byte-code compiled.
|
||||
:param Bundle bundle: Bundle object where the module is located.
|
||||
:param (str,str) compatibility: Min and max versions of CP compatible with the mpy.
|
||||
"""
|
||||
self.name = name
|
||||
self.backend = backend
|
||||
self.path = (
|
||||
urljoin(backend.library_path, name, allow_fragments=False)
|
||||
if isinstance(backend, WebBackend)
|
||||
else os.path.join(backend.library_path, name)
|
||||
)
|
||||
|
||||
url = urlparse(self.path, allow_fragments=False)
|
||||
|
||||
if (
|
||||
url.path.endswith("/")
|
||||
if isinstance(backend, WebBackend)
|
||||
else self.path.endswith(os.sep)
|
||||
):
|
||||
self.file = None
|
||||
self.name = self.path.split(
|
||||
"/" if isinstance(backend, WebBackend) else os.sep
|
||||
)[-2]
|
||||
else:
|
||||
self.file = os.path.basename(url.path)
|
||||
self.name = (
|
||||
os.path.basename(url.path).replace(".py", "").replace(".mpy", "")
|
||||
)
|
||||
|
||||
self.repo = repo
|
||||
self.device_version = device_version
|
||||
self.bundle_version = bundle_version
|
||||
self.mpy = mpy
|
||||
self.min_version = compatibility[0]
|
||||
self.max_version = compatibility[1]
|
||||
# Figure out the bundle path.
|
||||
self.bundle_path = None
|
||||
if self.mpy:
|
||||
# Byte compiled, now check CircuitPython version.
|
||||
|
||||
major_version = CPY_VERSION.split(".")[0]
|
||||
bundle_platform = "{}mpy".format(major_version)
|
||||
else:
|
||||
# Regular Python
|
||||
bundle_platform = "py"
|
||||
# module path in the bundle
|
||||
search_path = bundle.lib_dir(bundle_platform)
|
||||
if self.file:
|
||||
self.bundle_path = os.path.join(search_path, self.file)
|
||||
else:
|
||||
self.bundle_path = os.path.join(search_path, self.name)
|
||||
logger.info(self)
|
||||
|
||||
# pylint: enable=too-many-arguments
|
||||
|
||||
@property
|
||||
def outofdate(self):
|
||||
"""
|
||||
Returns a boolean to indicate if this module is out of date.
|
||||
Treat mismatched MPY versions as out of date.
|
||||
|
||||
:return: Truthy indication if the module is out of date.
|
||||
"""
|
||||
if self.mpy_mismatch:
|
||||
return True
|
||||
if self.device_version and self.bundle_version:
|
||||
try:
|
||||
return VersionInfo.parse(self.device_version) < VersionInfo.parse(
|
||||
self.bundle_version
|
||||
)
|
||||
except ValueError as ex:
|
||||
logger.warning("Module '%s' has incorrect semver value.", self.name)
|
||||
logger.warning(ex)
|
||||
return True # Assume out of date to try to update.
|
||||
|
||||
@property
|
||||
def bad_format(self):
|
||||
"""A boolean indicating that the mpy file format could not be identified"""
|
||||
return self.mpy and self.device_version == BAD_FILE_FORMAT
|
||||
|
||||
@property
|
||||
def mpy_mismatch(self):
|
||||
"""
|
||||
Returns a boolean to indicate if this module's MPY version is compatible
|
||||
with the board's current version of Circuitpython. A min or max version
|
||||
that evals to False means no limit.
|
||||
|
||||
:return: Boolean indicating if the MPY versions don't match.
|
||||
"""
|
||||
if not self.mpy:
|
||||
return False
|
||||
try:
|
||||
cpv = VersionInfo.parse(CPY_VERSION)
|
||||
except ValueError as ex:
|
||||
logger.warning("CircuitPython has incorrect semver value.")
|
||||
logger.warning(ex)
|
||||
try:
|
||||
if self.min_version and cpv < VersionInfo.parse(self.min_version):
|
||||
return True # CP version too old
|
||||
if self.max_version and cpv >= VersionInfo.parse(self.max_version):
|
||||
return True # MPY version too old
|
||||
except (TypeError, ValueError) as ex:
|
||||
logger.warning(
|
||||
"Module '%s' has incorrect MPY compatibility information.", self.name
|
||||
)
|
||||
logger.warning(ex)
|
||||
return False
|
||||
|
||||
@property
|
||||
def major_update(self):
|
||||
"""
|
||||
Returns a boolean to indicate if this is a major version update.
|
||||
|
||||
:return: Boolean indicating if this is a major version upgrade
|
||||
"""
|
||||
try:
|
||||
if (
|
||||
VersionInfo.parse(self.device_version).major
|
||||
== VersionInfo.parse(self.bundle_version).major
|
||||
):
|
||||
return False
|
||||
except (TypeError, ValueError) as ex:
|
||||
logger.warning("Module '%s' has incorrect semver value.", self.name)
|
||||
logger.warning(ex)
|
||||
return True # Assume Major Version udpate.
|
||||
|
||||
@property
|
||||
def row(self):
|
||||
"""
|
||||
Returns a tuple of items to display in a table row to show the module's
|
||||
name, local version and remote version, and reason to update.
|
||||
|
||||
:return: A tuple containing the module's name, version on the connected
|
||||
device, version in the latest bundle and reason to update.
|
||||
"""
|
||||
loc = self.device_version if self.device_version else "unknown"
|
||||
rem = self.bundle_version if self.bundle_version else "unknown"
|
||||
if self.mpy_mismatch:
|
||||
update_reason = "MPY Format"
|
||||
elif self.major_update:
|
||||
update_reason = "Major Version"
|
||||
else:
|
||||
update_reason = "Minor Version"
|
||||
return (self.name, loc, rem, update_reason)
|
||||
|
||||
def __repr__(self):
|
||||
"""
|
||||
Helps with log files.
|
||||
|
||||
:return: A repr of a dictionary containing the module's metadata.
|
||||
"""
|
||||
return repr(
|
||||
{
|
||||
"path": self.path,
|
||||
"file": self.file,
|
||||
"name": self.name,
|
||||
"repo": self.repo,
|
||||
"device_version": self.device_version,
|
||||
"bundle_version": self.bundle_version,
|
||||
"bundle_path": self.bundle_path,
|
||||
"mpy": self.mpy,
|
||||
"min_version": self.min_version,
|
||||
"max_version": self.max_version,
|
||||
}
|
||||
)
|
||||
Loading…
Reference in a new issue