move libraries_from_code_py out of backend. fix CPY_VERSION issue for web backend
This commit is contained in:
parent
fb6cd847a8
commit
499dee6e03
3 changed files with 53 additions and 40 deletions
|
|
@ -30,9 +30,12 @@ import update_checker
|
|||
from requests.auth import HTTPBasicAuth
|
||||
from semver import VersionInfo
|
||||
|
||||
from circup.shared import DATA_DIR, BAD_FILE_FORMAT, extract_metadata, CPY_VERSION, _get_modules_file
|
||||
from circup.shared import DATA_DIR, BAD_FILE_FORMAT, extract_metadata, _get_modules_file
|
||||
from circup.backends import WebBackend, DiskBackend
|
||||
|
||||
#: The version of CircuitPython found on the connected device.
|
||||
CPY_VERSION = ""
|
||||
|
||||
# Useful constants.
|
||||
#: Flag to indicate if the command is being run in verbose mode.
|
||||
VERBOSE = False
|
||||
|
|
@ -410,13 +413,6 @@ class Module:
|
|||
)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def clean_library_name(assumed_library_name):
|
||||
"""
|
||||
Most CP repos and library names are look like this:
|
||||
|
|
@ -505,9 +501,6 @@ def ensure_latest_bundle(bundle):
|
|||
logger.info("Current bundle up to date %s.", tag)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def find_device():
|
||||
"""
|
||||
Return the location on the filesystem for the connected CircuitPython device.
|
||||
|
|
@ -936,6 +929,25 @@ def tags_data_save_tag(key, tag):
|
|||
json.dump(tags_data, data)
|
||||
|
||||
|
||||
def libraries_from_code_py(code_py, mod_names):
|
||||
"""
|
||||
Parse the given code.py file and return the imported libraries
|
||||
|
||||
:param str code_py: Full path of the code.py file
|
||||
:return: sequence of library names
|
||||
"""
|
||||
# pylint: disable=broad-except
|
||||
try:
|
||||
found_imports = findimports.find_imports(code_py)
|
||||
except Exception as ex: # broad exception because anything could go wrong
|
||||
self.logger.exception(ex)
|
||||
click.secho('Unable to read the auto file: "{}"'.format(str(ex)), fg="red")
|
||||
sys.exit(2)
|
||||
# pylint: enable=broad-except
|
||||
imports = [info.name.split(".", 1)[0] for info in found_imports]
|
||||
return [r for r in imports if r in mod_names]
|
||||
|
||||
|
||||
# ----------- CLI command definitions ----------- #
|
||||
|
||||
# The following functions have IO side effects (for instance they emit to
|
||||
|
|
@ -1014,7 +1026,6 @@ def main(ctx, verbose, path, host, password, board_id, cpy_version): # pragma:
|
|||
if ctx.invoked_subcommand in BOARDLESS_COMMANDS:
|
||||
return
|
||||
|
||||
|
||||
ctx.obj["DEVICE_PATH"] = device_path
|
||||
latest_version = get_latest_release_from_url(
|
||||
"https://github.com/adafruit/circuitpython/releases/latest"
|
||||
|
|
@ -1213,9 +1224,10 @@ def install(ctx, modules, pyext, requirement, auto, auto_file): # pragma: no co
|
|||
if not os.path.isfile(auto_file) and not ctx.obj["using_webworkflow"]:
|
||||
click.secho(f"Auto file not found: {auto_file}", fg="red")
|
||||
sys.exit(1)
|
||||
requested_installs = ctx.obj["backend"].libraries_from_imports(
|
||||
auto_file, mod_names
|
||||
)
|
||||
|
||||
auto_file_path = ctx.obj["backend"].get_auto_file_path(auto_file)
|
||||
|
||||
requested_installs = libraries_from_code_py(auto_file_path, mod_names)
|
||||
else:
|
||||
requested_installs = modules
|
||||
requested_installs = sorted(set(requested_installs))
|
||||
|
|
|
|||
|
|
@ -9,12 +9,13 @@ import findimports
|
|||
import requests
|
||||
from requests.auth import HTTPBasicAuth
|
||||
|
||||
from circup.shared import DATA_DIR, BAD_FILE_FORMAT, extract_metadata, CPY_VERSION, _get_modules_file
|
||||
from circup.shared import DATA_DIR, BAD_FILE_FORMAT, extract_metadata, _get_modules_file
|
||||
|
||||
#: The location to store a local copy of code.py for use with --auto and
|
||||
# web workflow
|
||||
LOCAL_CODE_PY_COPY = os.path.join(DATA_DIR, "code.tmp.py")
|
||||
|
||||
|
||||
class Backend:
|
||||
"""
|
||||
Backend parent class to be extended for workflow specific
|
||||
|
|
@ -142,23 +143,6 @@ class Backend:
|
|||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def libraries_from_code_py(self, code_py, mod_names):
|
||||
"""
|
||||
Parse the given code.py file and return the imported libraries
|
||||
|
||||
:param str code_py: Full path of the code.py file
|
||||
:return: sequence of library names
|
||||
"""
|
||||
# pylint: disable=broad-except
|
||||
try:
|
||||
found_imports = findimports.find_imports(code_py)
|
||||
except Exception as ex: # broad exception because anything could go wrong
|
||||
self.logger.exception(ex)
|
||||
click.secho('Unable to read the auto file: "{}"'.format(str(ex)), fg="red")
|
||||
sys.exit(2)
|
||||
# pylint: enable=broad-except
|
||||
imports = [info.name.split(".", 1)[0] for info in found_imports]
|
||||
return [r for r in imports if r in mod_names]
|
||||
|
||||
class WebBackend(Backend):
|
||||
"""
|
||||
|
|
@ -170,6 +154,7 @@ class WebBackend(Backend):
|
|||
self.LIB_DIR_PATH = "fs/lib/"
|
||||
self.host = host
|
||||
self.password = password
|
||||
self.device_location = f"http://:{self.password}@{self.host}"
|
||||
|
||||
def install_file_http(self, source, target):
|
||||
"""
|
||||
|
|
@ -348,7 +333,9 @@ class WebBackend(Backend):
|
|||
if not module_name:
|
||||
# Must be a directory based module.
|
||||
module_name = os.path.basename(os.path.dirname(metadata["path"]))
|
||||
major_version = CPY_VERSION.split(".")[0]
|
||||
major_version = self.get_circuitpython_version(self.device_location)[0].split(
|
||||
"."
|
||||
)[0]
|
||||
bundle_platform = "{}mpy".format(major_version)
|
||||
bundle_path = os.path.join(bundle.lib_dir(bundle_platform), module_name)
|
||||
if os.path.isdir(bundle_path):
|
||||
|
|
@ -378,6 +365,16 @@ class WebBackend(Backend):
|
|||
target = os.path.basename(source_path)
|
||||
self.install_file_http(source_path, library_path + target)
|
||||
|
||||
def get_auto_file_path(self, auto_file_path):
|
||||
url = auto_file_path
|
||||
auth = HTTPBasicAuth("", self.password)
|
||||
r = requests.get(url, auth=auth)
|
||||
r.raise_for_status()
|
||||
with open(LOCAL_CODE_PY_COPY, "w", encoding="utf-8") as f:
|
||||
f.write(r.text)
|
||||
LOCAL_CODE_PY_COPY
|
||||
return LOCAL_CODE_PY_COPY
|
||||
|
||||
def libraries_from_imports(self, code_py, mod_names):
|
||||
"""
|
||||
Parse the given code.py file and return the imported libraries
|
||||
|
|
@ -428,6 +425,7 @@ class WebBackend(Backend):
|
|||
r.raise_for_status()
|
||||
self.install_dir_http(module.bundle_path, module.path)
|
||||
|
||||
|
||||
class DiskBackend(Backend):
|
||||
"""
|
||||
Backend for interacting with a device via USB Workflow
|
||||
|
|
@ -500,7 +498,9 @@ class DiskBackend(Backend):
|
|||
# Must be a directory based module.
|
||||
module_name = os.path.basename(os.path.dirname(metadata["path"]))
|
||||
|
||||
major_version = self.get_circuitpython_version(self.device_location)[0].split(".")[0]
|
||||
major_version = self.get_circuitpython_version(self.device_location)[0].split(
|
||||
"."
|
||||
)[0]
|
||||
bundle_platform = "{}mpy".format(major_version)
|
||||
bundle_path = os.path.join(bundle.lib_dir(bundle_platform), module_name)
|
||||
if os.path.isdir(bundle_path):
|
||||
|
|
@ -534,6 +534,9 @@ class DiskBackend(Backend):
|
|||
# Copy file.
|
||||
shutil.copyfile(source_path, target_path)
|
||||
|
||||
def get_auto_file_path(self, auto_file_path):
|
||||
return auto_file_path
|
||||
|
||||
def libraries_from_imports(self, code_py, mod_names):
|
||||
"""
|
||||
Parse the given code.py file and return the imported libraries
|
||||
|
|
@ -579,4 +582,4 @@ class DiskBackend(Backend):
|
|||
else:
|
||||
# Delete and copy file.
|
||||
os.remove(module.path)
|
||||
shutil.copyfile(module.bundle_path, module.path)
|
||||
shutil.copyfile(module.bundle_path, module.path)
|
||||
|
|
|
|||
|
|
@ -10,9 +10,6 @@ BAD_FILE_FORMAT = "Invalid"
|
|||
#: The location of data files used by circup (following OS conventions).
|
||||
DATA_DIR = appdirs.user_data_dir(appname="circup", appauthor="adafruit")
|
||||
|
||||
#: The version of CircuitPython found on the connected device.
|
||||
CPY_VERSION = ""
|
||||
|
||||
|
||||
def _get_modules_file(path, logger):
|
||||
"""
|
||||
|
|
@ -55,6 +52,7 @@ def _get_modules_file(path, logger):
|
|||
break
|
||||
return result
|
||||
|
||||
|
||||
def extract_metadata(path, logger):
|
||||
"""
|
||||
Given a file path, return a dictionary containing metadata extracted from
|
||||
|
|
@ -124,4 +122,4 @@ def extract_metadata(path, logger):
|
|||
|
||||
if result:
|
||||
logger.info("Extracted metadata: %s", result)
|
||||
return result
|
||||
return result
|
||||
|
|
|
|||
Loading…
Reference in a new issue