circup 2.0.2__tar.gz → 2.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {circup-2.0.2 → circup-2.0.4}/.pre-commit-config.yaml +1 -1
- {circup-2.0.2 → circup-2.0.4}/.pylintrc +1 -1
- {circup-2.0.2/circup.egg-info → circup-2.0.4}/PKG-INFO +1 -1
- {circup-2.0.2 → circup-2.0.4}/circup/backends.py +6 -2
- {circup-2.0.2 → circup-2.0.4}/circup/command_utils.py +2 -2
- {circup-2.0.2 → circup-2.0.4}/circup/commands.py +34 -4
- {circup-2.0.2 → circup-2.0.4}/circup/shared.py +3 -4
- {circup-2.0.2 → circup-2.0.4/circup.egg-info}/PKG-INFO +1 -1
- {circup-2.0.2 → circup-2.0.4}/.github/ISSUE_TEMPLATE.md +0 -0
- {circup-2.0.2 → circup-2.0.4}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {circup-2.0.2 → circup-2.0.4}/.github/workflows/build.yml +0 -0
- {circup-2.0.2 → circup-2.0.4}/.github/workflows/release.yml +0 -0
- {circup-2.0.2 → circup-2.0.4}/.gitignore +0 -0
- {circup-2.0.2 → circup-2.0.4}/.isort.cfg +0 -0
- {circup-2.0.2 → circup-2.0.4}/CODE_OF_CONDUCT.rst +0 -0
- {circup-2.0.2 → circup-2.0.4}/CODE_OF_CONDUCT.rst.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/CONTRIBUTING.rst +0 -0
- {circup-2.0.2 → circup-2.0.4}/CONTRIBUTING.rst.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/LICENSE +0 -0
- {circup-2.0.2 → circup-2.0.4}/LICENSES/CC-BY-4.0.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/LICENSES/MIT.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/LICENSES/Unlicense.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/README.rst +0 -0
- {circup-2.0.2 → circup-2.0.4}/README.rst.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup/__init__.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup/bundle.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup/config/bundle_config.json +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup/config/bundle_config.json.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup/logging.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup/module.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup.egg-info/SOURCES.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup.egg-info/dependency_links.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup.egg-info/entry_points.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup.egg-info/requires.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/circup.egg-info/top_level.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/docs/_static/favicon.ico +0 -0
- {circup-2.0.2 → circup-2.0.4}/docs/_static/favicon.ico.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/docs/conf.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/docs/index.rst +0 -0
- {circup-2.0.2 → circup-2.0.4}/docs/index.rst.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/docs/logo.png +0 -0
- {circup-2.0.2 → circup-2.0.4}/docs/logo.png.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/optional_requirements.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/optional_requirements.txt.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/pyproject.toml +0 -0
- {circup-2.0.2 → circup-2.0.4}/readthedocs.yml +0 -0
- {circup-2.0.2 → circup-2.0.4}/requirements.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/requirements.txt.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/setup.cfg +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/__init__.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/bad_module/__init__.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/bad_module/my_module.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/bad_python.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/bundle.json +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/bundle.json.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/device.json +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/device.json.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/dir_module/__init__.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/dir_module/my_module.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/import_styles.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/local_module.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/local_module_cp7.mpy +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/local_module_cp7.mpy.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/mock_device/boot_out.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/mock_device/boot_out.txt.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/mock_device/lib/adafruit_waveform/.gitkeep +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/mount_exists.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/mount_exists.txt.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/mount_missing.txt +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/mount_missing.txt.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/remote_module.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/test_bundle_config.json +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/test_bundle_config.json.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/test_bundle_config_local.json +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/test_bundle_config_local.json.license +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/test_circup.py +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/test_module.mpy +0 -0
- {circup-2.0.2 → circup-2.0.4}/tests/test_module.mpy.license +0 -0
|
@@ -277,7 +277,7 @@ class WebBackend(Backend):
|
|
|
277
277
|
"""
|
|
278
278
|
|
|
279
279
|
def __init__( # pylint: disable=too-many-arguments
|
|
280
|
-
self, host, password, logger, timeout=10, version_override=None
|
|
280
|
+
self, host, port, password, logger, timeout=10, version_override=None
|
|
281
281
|
):
|
|
282
282
|
super().__init__(logger)
|
|
283
283
|
if password is None:
|
|
@@ -297,8 +297,9 @@ class WebBackend(Backend):
|
|
|
297
297
|
self.FS_PATH = "fs/"
|
|
298
298
|
self.LIB_DIR_PATH = f"{self.FS_PATH}lib/"
|
|
299
299
|
self.host = host
|
|
300
|
+
self.port = port
|
|
300
301
|
self.password = password
|
|
301
|
-
self.device_location = f"http://:{self.password}@{self.host}"
|
|
302
|
+
self.device_location = f"http://:{self.password}@{self.host}:{self.port}"
|
|
302
303
|
|
|
303
304
|
self.session = requests.Session()
|
|
304
305
|
self.session.mount(self.device_location, HTTPAdapter(max_retries=5))
|
|
@@ -306,6 +307,9 @@ class WebBackend(Backend):
|
|
|
306
307
|
self.timeout = timeout
|
|
307
308
|
self.version_override = version_override
|
|
308
309
|
|
|
310
|
+
def __repr__(self):
|
|
311
|
+
return f"<WebBackend @{self.device_location}>"
|
|
312
|
+
|
|
309
313
|
def install_file_http(self, source, location=None):
|
|
310
314
|
"""
|
|
311
315
|
Install file to device using web workflow.
|
|
@@ -610,7 +610,7 @@ def libraries_from_code_py(code_py, mod_names):
|
|
|
610
610
|
return [r for r in imports if r in mod_names]
|
|
611
611
|
|
|
612
612
|
|
|
613
|
-
def get_device_path(host, password, path):
|
|
613
|
+
def get_device_path(host, port, password, path):
|
|
614
614
|
"""
|
|
615
615
|
:param host Hostname or IP address.
|
|
616
616
|
:param password REST API password.
|
|
@@ -621,7 +621,7 @@ def get_device_path(host, password, path):
|
|
|
621
621
|
device_path = path
|
|
622
622
|
elif host:
|
|
623
623
|
# pylint: enable=no-member
|
|
624
|
-
device_path = f"http://:{password}@"
|
|
624
|
+
device_path = f"http://:{password}@{host}:{port}"
|
|
625
625
|
else:
|
|
626
626
|
device_path = find_device()
|
|
627
627
|
return device_path
|
|
@@ -11,6 +11,7 @@ and the respective Backends which *are* tested. Most of the logic of the followi
|
|
|
11
11
|
functions is to prepare things for presentation to / interaction with the user.
|
|
12
12
|
"""
|
|
13
13
|
import os
|
|
14
|
+
import subprocess
|
|
14
15
|
import time
|
|
15
16
|
import sys
|
|
16
17
|
import re
|
|
@@ -56,6 +57,9 @@ from circup.command_utils import (
|
|
|
56
57
|
"--host",
|
|
57
58
|
help="Hostname or IP address of a device. Overrides automatic path detection.",
|
|
58
59
|
)
|
|
60
|
+
@click.option(
|
|
61
|
+
"--port", help="Port to contact. Overrides automatic path detection.", default=80
|
|
62
|
+
)
|
|
59
63
|
@click.option(
|
|
60
64
|
"--password",
|
|
61
65
|
help="Password to use for authentication when --host is used."
|
|
@@ -85,7 +89,7 @@ from circup.command_utils import (
|
|
|
85
89
|
)
|
|
86
90
|
@click.pass_context
|
|
87
91
|
def main( # pylint: disable=too-many-locals
|
|
88
|
-
ctx, verbose, path, host, password, timeout, board_id, cpy_version
|
|
92
|
+
ctx, verbose, path, host, port, password, timeout, board_id, cpy_version
|
|
89
93
|
): # pragma: no cover
|
|
90
94
|
"""
|
|
91
95
|
A tool to manage and update libraries on a CircuitPython device.
|
|
@@ -97,7 +101,7 @@ def main( # pylint: disable=too-many-locals
|
|
|
97
101
|
if password is None:
|
|
98
102
|
password = os.getenv("CIRCUP_WEBWORKFLOW_PASSWORD")
|
|
99
103
|
|
|
100
|
-
device_path = get_device_path(host, password, path)
|
|
104
|
+
device_path = get_device_path(host, port, password, path)
|
|
101
105
|
|
|
102
106
|
using_webworkflow = "host" in ctx.params.keys() and ctx.params["host"] is not None
|
|
103
107
|
|
|
@@ -113,6 +117,7 @@ def main( # pylint: disable=too-many-locals
|
|
|
113
117
|
try:
|
|
114
118
|
ctx.obj["backend"] = WebBackend(
|
|
115
119
|
host=host,
|
|
120
|
+
port=port,
|
|
116
121
|
password=password,
|
|
117
122
|
logger=logger,
|
|
118
123
|
timeout=timeout,
|
|
@@ -304,6 +309,12 @@ def list_cli(ctx): # pragma: no cover
|
|
|
304
309
|
@click.option(
|
|
305
310
|
"--upgrade", "-U", is_flag=True, help="Upgrade modules that are already installed."
|
|
306
311
|
)
|
|
312
|
+
@click.option(
|
|
313
|
+
"--stubs",
|
|
314
|
+
"-s",
|
|
315
|
+
is_flag=True,
|
|
316
|
+
help="Install stubs module from PyPi for context in IDE.",
|
|
317
|
+
)
|
|
307
318
|
@click.option(
|
|
308
319
|
"--auto-file",
|
|
309
320
|
default=None,
|
|
@@ -312,7 +323,7 @@ def list_cli(ctx): # pragma: no cover
|
|
|
312
323
|
)
|
|
313
324
|
@click.pass_context
|
|
314
325
|
def install(
|
|
315
|
-
ctx, modules, pyext, requirement, auto, auto_file, upgrade=False
|
|
326
|
+
ctx, modules, pyext, requirement, auto, auto_file, upgrade=False, stubs=False
|
|
316
327
|
): # pragma: no cover
|
|
317
328
|
"""
|
|
318
329
|
Install a named module(s) onto the device. Multiple modules
|
|
@@ -320,6 +331,7 @@ def install(
|
|
|
320
331
|
separated by a space. Modules can be from a Bundle or local filepaths.
|
|
321
332
|
"""
|
|
322
333
|
|
|
334
|
+
# pylint: disable=too-many-branches
|
|
323
335
|
# TODO: Ensure there's enough space on the device
|
|
324
336
|
available_modules = get_bundle_versions(get_bundles_list())
|
|
325
337
|
mod_names = {}
|
|
@@ -373,6 +385,24 @@ def install(
|
|
|
373
385
|
upgrade,
|
|
374
386
|
)
|
|
375
387
|
|
|
388
|
+
if stubs:
|
|
389
|
+
library_stubs = "adafruit-circuitpython-{}".format(
|
|
390
|
+
library.replace("adafruit_", "")
|
|
391
|
+
)
|
|
392
|
+
try:
|
|
393
|
+
output = subprocess.check_output(["pip", "install", library_stubs])
|
|
394
|
+
if (
|
|
395
|
+
f"Requirement already satisfied: {library_stubs}"
|
|
396
|
+
in output.decode()
|
|
397
|
+
):
|
|
398
|
+
click.echo(f"'{library}' stubs already installed.")
|
|
399
|
+
else:
|
|
400
|
+
click.echo(f"Installed '{library}' stubs.")
|
|
401
|
+
except subprocess.CalledProcessError:
|
|
402
|
+
click.secho(
|
|
403
|
+
f"Could not install stubs module {library_stubs}", fg="yellow"
|
|
404
|
+
)
|
|
405
|
+
|
|
376
406
|
|
|
377
407
|
@main.command()
|
|
378
408
|
@click.option("--overwrite", is_flag=True, help="Overwrite the file if it exists.")
|
|
@@ -697,7 +727,7 @@ def bundle_remove(bundle, reset):
|
|
|
697
727
|
bundles_local_dict = get_bundles_local_dict()
|
|
698
728
|
modified = False
|
|
699
729
|
for bun in bundle:
|
|
700
|
-
# cleanup in case
|
|
730
|
+
# cleanup in case somebody pastes the URL to the repo/releases
|
|
701
731
|
bun = re.sub(r"https?://github.com/([^/]+/[^/]+)(/.*)?", r"\1", bun)
|
|
702
732
|
found = False
|
|
703
733
|
for name, repo in list(bundles_local_dict.items()):
|
|
@@ -10,8 +10,8 @@ import glob
|
|
|
10
10
|
import os
|
|
11
11
|
import re
|
|
12
12
|
import json
|
|
13
|
+
import importlib.resources
|
|
13
14
|
import appdirs
|
|
14
|
-
import pkg_resources
|
|
15
15
|
import requests
|
|
16
16
|
|
|
17
17
|
#: Version identifier for a bad MPY file format
|
|
@@ -27,9 +27,8 @@ PLATFORMS = {"py": "py", "8mpy": "8.x-mpy", "9mpy": "9.x-mpy"}
|
|
|
27
27
|
REQUESTS_TIMEOUT = 30
|
|
28
28
|
|
|
29
29
|
#: The path to the JSON file containing the metadata about the bundles.
|
|
30
|
-
BUNDLE_CONFIG_FILE =
|
|
31
|
-
|
|
32
|
-
)
|
|
30
|
+
BUNDLE_CONFIG_FILE = importlib.resources.files("circup") / "config/bundle_config.json"
|
|
31
|
+
|
|
33
32
|
#: Overwrite the bundles list with this file (only done manually)
|
|
34
33
|
BUNDLE_CONFIG_OVERWRITE = os.path.join(DATA_DIR, "bundle_config.json")
|
|
35
34
|
#: The path to the JSON file containing the local list of bundles.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|