circup 1.6.1__tar.gz → 1.7.0__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-1.6.1 → circup-1.7.0}/.gitignore +2 -0
- {circup-1.6.1/circup.egg-info → circup-1.7.0}/PKG-INFO +6 -6
- circup-1.7.0/circup/__init__.py +26 -0
- {circup-1.6.1 → circup-1.7.0}/circup/backends.py +20 -3
- circup-1.7.0/circup/bundle.py +156 -0
- circup-1.7.0/circup/command_utils.py +562 -0
- circup-1.7.0/circup/commands.py +657 -0
- circup-1.7.0/circup/logging.py +33 -0
- circup-1.7.0/circup/module.py +209 -0
- {circup-1.6.1 → circup-1.7.0}/circup/shared.py +75 -1
- {circup-1.6.1 → circup-1.7.0/circup.egg-info}/PKG-INFO +6 -6
- {circup-1.6.1 → circup-1.7.0}/circup.egg-info/SOURCES.txt +9 -1
- {circup-1.6.1 → circup-1.7.0}/docs/conf.py +1 -1
- circup-1.7.0/optional_requirements.txt +4 -0
- circup-1.7.0/optional_requirements.txt.license +3 -0
- circup-1.7.0/requirements.txt +7 -0
- {circup-1.6.1 → circup-1.7.0}/tests/mock_device/boot_out.txt +1 -1
- circup-1.7.0/tests/mock_device/lib/adafruit_waveform/.gitkeep +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/test_circup.py +198 -197
- circup-1.6.1/circup/__init__.py +0 -1584
- circup-1.6.1/requirements.txt +0 -58
- {circup-1.6.1 → circup-1.7.0}/.github/ISSUE_TEMPLATE.md +0 -0
- {circup-1.6.1 → circup-1.7.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {circup-1.6.1 → circup-1.7.0}/.github/workflows/build.yml +0 -0
- {circup-1.6.1 → circup-1.7.0}/.github/workflows/release.yml +0 -0
- {circup-1.6.1 → circup-1.7.0}/.isort.cfg +0 -0
- {circup-1.6.1 → circup-1.7.0}/.pre-commit-config.yaml +0 -0
- {circup-1.6.1 → circup-1.7.0}/.pylintrc +0 -0
- {circup-1.6.1 → circup-1.7.0}/CODE_OF_CONDUCT.rst +0 -0
- {circup-1.6.1 → circup-1.7.0}/CODE_OF_CONDUCT.rst.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/CONTRIBUTING.rst +0 -0
- {circup-1.6.1 → circup-1.7.0}/CONTRIBUTING.rst.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/LICENSE +0 -0
- {circup-1.6.1 → circup-1.7.0}/LICENSES/CC-BY-4.0.txt +0 -0
- {circup-1.6.1 → circup-1.7.0}/LICENSES/MIT.txt +0 -0
- {circup-1.6.1 → circup-1.7.0}/LICENSES/Unlicense.txt +0 -0
- {circup-1.6.1 → circup-1.7.0}/README.rst +0 -0
- {circup-1.6.1 → circup-1.7.0}/README.rst.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/circup/config/bundle_config.json +0 -0
- {circup-1.6.1 → circup-1.7.0}/circup/config/bundle_config.json.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/circup.egg-info/dependency_links.txt +0 -0
- {circup-1.6.1 → circup-1.7.0}/circup.egg-info/entry_points.txt +0 -0
- {circup-1.6.1 → circup-1.7.0}/circup.egg-info/requires.txt +5 -5
- {circup-1.6.1 → circup-1.7.0}/circup.egg-info/top_level.txt +0 -0
- {circup-1.6.1 → circup-1.7.0}/docs/_static/favicon.ico +0 -0
- {circup-1.6.1 → circup-1.7.0}/docs/_static/favicon.ico.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/docs/index.rst +0 -0
- {circup-1.6.1 → circup-1.7.0}/docs/index.rst.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/docs/logo.png +0 -0
- {circup-1.6.1 → circup-1.7.0}/docs/logo.png.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/readthedocs.yml +0 -0
- {circup-1.6.1 → circup-1.7.0}/requirements.txt.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/setup.cfg +0 -0
- {circup-1.6.1 → circup-1.7.0}/setup.py +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/__init__.py +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/bad_module/__init__.py +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/bad_module/my_module.py +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/bad_python.py +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/bundle.json +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/bundle.json.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/device.json +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/device.json.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/dir_module/__init__.py +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/dir_module/my_module.py +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/import_styles.py +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/local_module.py +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/local_module_cp7.mpy +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/local_module_cp7.mpy.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/mock_device/boot_out.txt.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/mount_exists.txt +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/mount_exists.txt.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/mount_missing.txt +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/mount_missing.txt.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/remote_module.py +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/test_bundle_config.json +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/test_bundle_config.json.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/test_bundle_config_local.json +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/test_bundle_config_local.json.license +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/test_module.mpy +0 -0
- {circup-1.6.1 → circup-1.7.0}/tests/test_module.mpy.license +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: circup
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.0
|
|
4
4
|
Summary: A tool to manage/update libraries on CircuitPython devices.
|
|
5
5
|
Home-page: https://github.com/adafruit/circup
|
|
6
6
|
Author: Adafruit Industries
|
|
@@ -57,16 +57,16 @@ Requires-Dist: sphinx; extra == "dev"
|
|
|
57
57
|
Requires-Dist: wheel; extra == "dev"
|
|
58
58
|
Requires-Dist: twine; extra == "dev"
|
|
59
59
|
Provides-Extra: all
|
|
60
|
-
Requires-Dist: pytest-faulthandler; extra == "all"
|
|
61
|
-
Requires-Dist: pylint; extra == "all"
|
|
62
60
|
Requires-Dist: wheel; extra == "all"
|
|
61
|
+
Requires-Dist: pytest-faulthandler; extra == "all"
|
|
63
62
|
Requires-Dist: pytest-random-order>=1.0.0; extra == "all"
|
|
63
|
+
Requires-Dist: pylint; extra == "all"
|
|
64
|
+
Requires-Dist: pytest; extra == "all"
|
|
64
65
|
Requires-Dist: coverage; extra == "all"
|
|
65
66
|
Requires-Dist: black; extra == "all"
|
|
66
|
-
Requires-Dist: sphinx; extra == "all"
|
|
67
|
-
Requires-Dist: twine; extra == "all"
|
|
68
67
|
Requires-Dist: pytest-cov; extra == "all"
|
|
69
|
-
Requires-Dist:
|
|
68
|
+
Requires-Dist: twine; extra == "all"
|
|
69
|
+
Requires-Dist: sphinx; extra == "all"
|
|
70
70
|
|
|
71
71
|
|
|
72
72
|
CircUp
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2019 Nicholas Tollervey, written for Adafruit Industries
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
"""
|
|
5
|
+
CircUp -- a utility to manage and update libraries on a CircuitPython device.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
from circup.shared import DATA_DIR, BAD_FILE_FORMAT, extract_metadata, _get_modules_file
|
|
10
|
+
from circup.backends import WebBackend, DiskBackend
|
|
11
|
+
from circup.logging import logger
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# Useful constants.
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
__version__ = "0.0.0-auto.0"
|
|
18
|
+
__repo__ = "https://github.com/adafruit/circup.git"
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
from circup.commands import *
|
|
22
|
+
|
|
23
|
+
# Allows execution via `python -m circup ...`
|
|
24
|
+
# pylint: disable=no-value-for-parameter
|
|
25
|
+
if __name__ == "__main__": # pragma: no cover
|
|
26
|
+
main()
|
|
@@ -589,14 +589,31 @@ class WebBackend(Backend):
|
|
|
589
589
|
|
|
590
590
|
def is_device_present(self):
|
|
591
591
|
"""
|
|
592
|
-
returns True if the device is currently connected
|
|
592
|
+
returns True if the device is currently connected and running supported version
|
|
593
593
|
"""
|
|
594
594
|
try:
|
|
595
|
-
|
|
596
|
-
|
|
595
|
+
with self.session.get(f"{self.device_location}/cp/version.json") as r:
|
|
596
|
+
r.raise_for_status()
|
|
597
|
+
web_api_version = r.json().get("web_api_version")
|
|
598
|
+
if web_api_version is None:
|
|
599
|
+
self.logger.error("Unable to get web API version from device.")
|
|
600
|
+
click.secho("Unable to get web API version from device.", fg="red")
|
|
601
|
+
return False
|
|
602
|
+
|
|
603
|
+
if web_api_version < 4:
|
|
604
|
+
self.logger.error(
|
|
605
|
+
f"Device running unsupported web API version {web_api_version} < 4."
|
|
606
|
+
)
|
|
607
|
+
click.secho(
|
|
608
|
+
f"Device running unsupported web API version {web_api_version} < 4.",
|
|
609
|
+
fg="red",
|
|
610
|
+
)
|
|
611
|
+
return False
|
|
597
612
|
except requests.exceptions.ConnectionError:
|
|
598
613
|
return False
|
|
599
614
|
|
|
615
|
+
return True
|
|
616
|
+
|
|
600
617
|
def get_device_versions(self):
|
|
601
618
|
"""
|
|
602
619
|
Returns a dictionary of metadata from modules on the connected device.
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: 2019 Nicholas Tollervey, 2024 Tim Cocks, written for Adafruit Industries
|
|
2
|
+
#
|
|
3
|
+
# SPDX-License-Identifier: MIT
|
|
4
|
+
"""
|
|
5
|
+
Class that represents a specific release of a Bundle.
|
|
6
|
+
"""
|
|
7
|
+
import os
|
|
8
|
+
import sys
|
|
9
|
+
|
|
10
|
+
import click
|
|
11
|
+
import requests
|
|
12
|
+
|
|
13
|
+
from circup.shared import (
|
|
14
|
+
DATA_DIR,
|
|
15
|
+
PLATFORMS,
|
|
16
|
+
REQUESTS_TIMEOUT,
|
|
17
|
+
tags_data_load,
|
|
18
|
+
get_latest_release_from_url,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from circup.logging import logger
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
class Bundle:
|
|
25
|
+
"""
|
|
26
|
+
All the links and file names for a bundle
|
|
27
|
+
"""
|
|
28
|
+
|
|
29
|
+
def __init__(self, repo):
|
|
30
|
+
"""
|
|
31
|
+
Initialise a Bundle created from its github info.
|
|
32
|
+
Construct all the strings in one place.
|
|
33
|
+
|
|
34
|
+
:param str repo: Repository string for github: "user/repository"
|
|
35
|
+
"""
|
|
36
|
+
vendor, bundle_id = repo.split("/")
|
|
37
|
+
bundle_id = bundle_id.lower().replace("_", "-")
|
|
38
|
+
self.key = repo
|
|
39
|
+
#
|
|
40
|
+
self.url = "https://github.com/" + repo
|
|
41
|
+
self.basename = bundle_id + "-{platform}-{tag}"
|
|
42
|
+
self.urlzip = self.basename + ".zip"
|
|
43
|
+
self.dir = os.path.join(DATA_DIR, vendor, bundle_id + "-{platform}")
|
|
44
|
+
self.zip = os.path.join(DATA_DIR, bundle_id + "-{platform}.zip")
|
|
45
|
+
self.url_format = self.url + "/releases/download/{tag}/" + self.urlzip
|
|
46
|
+
# tag
|
|
47
|
+
self._current = None
|
|
48
|
+
self._latest = None
|
|
49
|
+
|
|
50
|
+
def lib_dir(self, platform):
|
|
51
|
+
"""
|
|
52
|
+
This bundle's lib directory for the platform.
|
|
53
|
+
|
|
54
|
+
:param str platform: The platform identifier (py/6mpy/...).
|
|
55
|
+
:return: The path to the lib directory for the platform.
|
|
56
|
+
"""
|
|
57
|
+
tag = self.current_tag
|
|
58
|
+
return os.path.join(
|
|
59
|
+
self.dir.format(platform=platform),
|
|
60
|
+
self.basename.format(platform=PLATFORMS[platform], tag=tag),
|
|
61
|
+
"lib",
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
def requirements_for(self, library_name, toml_file=False):
|
|
65
|
+
"""
|
|
66
|
+
The requirements file for this library.
|
|
67
|
+
|
|
68
|
+
:param str library_name: The name of the library.
|
|
69
|
+
:return: The path to the requirements.txt file.
|
|
70
|
+
"""
|
|
71
|
+
platform = "py"
|
|
72
|
+
tag = self.current_tag
|
|
73
|
+
found_file = os.path.join(
|
|
74
|
+
self.dir.format(platform=platform),
|
|
75
|
+
self.basename.format(platform=PLATFORMS[platform], tag=tag),
|
|
76
|
+
"requirements",
|
|
77
|
+
library_name,
|
|
78
|
+
"requirements.txt" if not toml_file else "pyproject.toml",
|
|
79
|
+
)
|
|
80
|
+
if os.path.isfile(found_file):
|
|
81
|
+
with open(found_file, "r", encoding="utf-8") as read_this:
|
|
82
|
+
return read_this.read()
|
|
83
|
+
return None
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def current_tag(self):
|
|
87
|
+
"""
|
|
88
|
+
Lazy load current cached tag from the BUNDLE_DATA json file.
|
|
89
|
+
|
|
90
|
+
:return: The current cached tag value for the project.
|
|
91
|
+
"""
|
|
92
|
+
if self._current is None:
|
|
93
|
+
self._current = tags_data_load(logger).get(self.key, "0")
|
|
94
|
+
return self._current
|
|
95
|
+
|
|
96
|
+
@current_tag.setter
|
|
97
|
+
def current_tag(self, tag):
|
|
98
|
+
"""
|
|
99
|
+
Set the current cached tag (after updating).
|
|
100
|
+
|
|
101
|
+
:param str tag: The new value for the current tag.
|
|
102
|
+
:return: The current cached tag value for the project.
|
|
103
|
+
"""
|
|
104
|
+
self._current = tag
|
|
105
|
+
|
|
106
|
+
@property
|
|
107
|
+
def latest_tag(self):
|
|
108
|
+
"""
|
|
109
|
+
Lazy find the value of the latest tag for the bundle.
|
|
110
|
+
|
|
111
|
+
:return: The most recent tag value for the project.
|
|
112
|
+
"""
|
|
113
|
+
if self._latest is None:
|
|
114
|
+
self._latest = get_latest_release_from_url(
|
|
115
|
+
self.url + "/releases/latest", logger
|
|
116
|
+
)
|
|
117
|
+
return self._latest
|
|
118
|
+
|
|
119
|
+
def validate(self):
|
|
120
|
+
"""
|
|
121
|
+
Test the existence of the expected URLs (not their content)
|
|
122
|
+
"""
|
|
123
|
+
tag = self.latest_tag
|
|
124
|
+
if not tag or tag == "releases":
|
|
125
|
+
if "--verbose" in sys.argv:
|
|
126
|
+
click.secho(f' Invalid tag "{tag}"', fg="red")
|
|
127
|
+
return False
|
|
128
|
+
for platform in PLATFORMS.values():
|
|
129
|
+
url = self.url_format.format(platform=platform, tag=tag)
|
|
130
|
+
r = requests.get(url, stream=True, timeout=REQUESTS_TIMEOUT)
|
|
131
|
+
# pylint: disable=no-member
|
|
132
|
+
if r.status_code != requests.codes.ok:
|
|
133
|
+
if "--verbose" in sys.argv:
|
|
134
|
+
click.secho(f" Unable to find {os.path.split(url)[1]}", fg="red")
|
|
135
|
+
return False
|
|
136
|
+
# pylint: enable=no-member
|
|
137
|
+
return True
|
|
138
|
+
|
|
139
|
+
def __repr__(self):
|
|
140
|
+
"""
|
|
141
|
+
Helps with log files.
|
|
142
|
+
|
|
143
|
+
:return: A repr of a dictionary containing the Bundles's metadata.
|
|
144
|
+
"""
|
|
145
|
+
return repr(
|
|
146
|
+
{
|
|
147
|
+
"key": self.key,
|
|
148
|
+
"url": self.url,
|
|
149
|
+
"urlzip": self.urlzip,
|
|
150
|
+
"dir": self.dir,
|
|
151
|
+
"zip": self.zip,
|
|
152
|
+
"url_format": self.url_format,
|
|
153
|
+
"current": self._current,
|
|
154
|
+
"latest": self._latest,
|
|
155
|
+
}
|
|
156
|
+
)
|