diff --git a/.gitignore b/.gitignore index e4a98b9..45d89a4 100644 --- a/.gitignore +++ b/.gitignore @@ -106,4 +106,7 @@ venv.bak/ # vim *.swp +# VSCode +.vscode/ + .DS_STORE diff --git a/circup.py b/circup.py index 50f54cd..ef1e318 100644 --- a/circup.py +++ b/circup.py @@ -146,7 +146,9 @@ class Module: try: return compare(self.device_version, self.bundle_version) < 0 except ValueError as ex: - logger.warning("Module '%s' has incorrect semver value.", self.name) + logger.warning( + "Module '%s' has incorrect semver value.", self.name + ) logger.warning(ex) return True # Assume out of date to try to update. @@ -254,7 +256,10 @@ def find_device(): try: for disk in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": path = "{}:\\".format(disk) - if os.path.exists(path) and get_volume_name(path) == "CIRCUITPY": + if ( + os.path.exists(path) + and get_volume_name(path) == "CIRCUITPY" + ): device_dir = path # Report only the FIRST device found. break @@ -311,7 +316,9 @@ def extract_metadata(path): if DUNDER_ASSIGN_RE.search(line): exec(line, result) if "__builtins__" in result: - del result["__builtins__"] # Side effect of using exec, not needed. + del result[ + "__builtins__" + ] # Side effect of using exec, not needed. if result: logger.info("Extracted metadata: %s", result) return result @@ -364,7 +371,9 @@ def find_modules(): device_version = device_metadata.get("__version__") bundle_version = bundle_metadata.get("__version__") mpy = device_metadata["mpy"] - result.append(Module(path, repo, device_version, bundle_version, mpy)) + result.append( + Module(path, repo, device_version, bundle_version, mpy) + ) return result except Exception as ex: # If it's not possible to get the device and bundle metadata, bail out @@ -439,17 +448,23 @@ def get_modules(path): if not os.path.basename(os.path.normpath(d)).startswith(".") ] single_file_mods = single_file_py_mods + single_file_mpy_mods - for sfm in [f for f in single_file_mods if not os.path.basename(f).startswith(".")]: + for sfm in [ + f for f in single_file_mods if not os.path.basename(f).startswith(".") + ]: metadata = extract_metadata(sfm) metadata["path"] = sfm - result[os.path.basename(sfm).replace(".py", "").replace(".mpy", "")] = metadata + result[ + os.path.basename(sfm).replace(".py", "").replace(".mpy", "") + ] = metadata for dm in directory_mods: name = os.path.basename(os.path.dirname(dm)) metadata = {} py_files = glob.glob(os.path.join(dm, "*.py")) mpy_files = glob.glob(os.path.join(dm, "*.mpy")) all_files = py_files + mpy_files - for source in [f for f in all_files if not os.path.basename(f).startswith(".")]: + for source in [ + f for f in all_files if not os.path.basename(f).startswith(".") + ]: metadata = extract_metadata(source) if "__version__" in metadata: metadata["path"] = dm @@ -516,12 +531,16 @@ def get_bundle(tag): "5mpy": ( "https://github.com/adafruit/Adafruit_CircuitPython_Bundle" "/releases/download" - "/{tag}/adafruit-circuitpython-bundle-5.x-mpy-{tag}.zip".format(tag=tag) + "/{tag}/adafruit-circuitpython-bundle-5.x-mpy-{tag}.zip".format( + tag=tag + ) ), "6mpy": ( "https://github.com/adafruit/Adafruit_CircuitPython_Bundle/" "releases/download" - "/{tag}/adafruit-circuitpython-bundle-6.x-mpy-{tag}.zip".format(tag=tag) + "/{tag}/adafruit-circuitpython-bundle-6.x-mpy-{tag}.zip".format( + tag=tag + ) ), } click.echo("Downloading latest version information.\n") @@ -535,9 +554,9 @@ def get_bundle(tag): # pylint: enable=no-member total_size = int(r.headers.get("Content-Length")) temp_zip = BUNDLE_ZIP.format(platform) - with click.progressbar(r.iter_content(1024), length=total_size) as pbar, open( - temp_zip, "wb" - ) as f: + with click.progressbar( + r.iter_content(1024), length=total_size + ) as pbar, open(temp_zip, "wb") as f: for chunk in pbar: f.write(chunk) pbar.update(len(chunk)) @@ -588,7 +607,9 @@ def main(verbose): # pragma: no cover global CPY_VERSION CPY_VERSION = get_circuitpython_version(device_path) click.echo( - "Found device at {}, running CircuitPython {}.".format(device_path, CPY_VERSION) + "Found device at {}, running CircuitPython {}.".format( + device_path, CPY_VERSION + ) ) cp_release = requests.get( "https://github.com/adafruit/circuitpython/releases/latest", timeout=2 @@ -627,7 +648,9 @@ def freeze(requirement): # pragma: no cover cwd = os.path.abspath(os.getcwd()) for i, module in enumerate(output): output[i] += "\n" - with open(cwd + "/" + "requirements.txt", "w", newline="\n") as file: + with open( + cwd + "/" + "requirements.txt", "w", newline="\n" + ) as file: file.truncate(0) file.writelines(output) else: @@ -653,7 +676,8 @@ def list(): # pragma: no cover dashes = tuple(("-" * (width - 1) for width in col_width)) data.insert(1, dashes) click.echo( - "The following modules are out of date or probably need " "an update.\n" + "The following modules are out of date or probably need " + "an update.\n" ) for row in data: output = "" @@ -697,7 +721,9 @@ def update(all): # pragma: no cover except Exception as ex: logger.exception(ex) click.echo( - "Something went wrong, {} (check the logs)".format(str(ex)) + "Something went wrong, {} (check the logs)".format( + str(ex) + ) ) # pylint: enable=broad-except else: @@ -763,10 +789,14 @@ def install_module(name, py, mod_names): # pragma: no cover shutil.copyfile(source_path, target_path) else: # Use pre-compiled mpy modules. - module_name = os.path.basename(metadata["path"]).replace(".py", ".mpy") + module_name = os.path.basename(metadata["path"]).replace( + ".py", ".mpy" + ) if not module_name: # Must be a directory based module. - module_name = os.path.basename(os.path.dirname(metadata["path"])) + module_name = os.path.basename( + os.path.dirname(metadata["path"]) + ) major_version = CPY_VERSION.split(".")[0] bundle_platform = "{}mpy".format(major_version) bundle_path = "" diff --git a/tests/test_circup.py b/tests/test_circup.py index d830266..40b87ee 100644 --- a/tests/test_circup.py +++ b/tests/test_circup.py @@ -131,7 +131,9 @@ def test_Module_row(): bundle_version = None bundle_path = os.path.join("baz", "bar", "foo", "module.py") with mock.patch("circup.os.path.isfile", return_value=True): - m = circup.Module(path, repo, device_version, bundle_version, bundle_path) + m = circup.Module( + path, repo, device_version, bundle_version, bundle_path + ) assert m.row == ("module", "1.2.3", "unknown") @@ -220,7 +222,9 @@ def test_find_device_posix_no_mount_command(): with open("tests/mount_exists.txt", "rb") as fixture_file: fixture = fixture_file.read() mock_check = mock.MagicMock(side_effect=[FileNotFoundError, fixture]) - with mock.patch("os.name", "posix"), mock.patch("circup.check_output", mock_check): + with mock.patch("os.name", "posix"), mock.patch( + "circup.check_output", mock_check + ): assert circup.find_device() == "/media/ntoll/CIRCUITPY" assert mock_check.call_count == 2 assert mock_check.call_args_list[0][0][0] == "mount" @@ -295,7 +299,8 @@ def test_get_latest_tag(): "/Adafruit_CircuitPython_Bundle/releases/tag/20190903" ) expected_url = ( - "https://github.com/adafruit/Adafruit_CircuitPython_Bundle" "/releases/latest" + "https://github.com/adafruit/Adafruit_CircuitPython_Bundle" + "/releases/latest" ) with mock.patch("circup.requests.get", return_value=response) as mock_get: result = circup.get_latest_tag() @@ -315,7 +320,9 @@ def test_extract_metadata_python(): 'print("Hello, world!")\n' ) path = "foo.py" - with mock.patch("builtins.open", mock.mock_open(read_data=code)) as mock_open: + with mock.patch( + "builtins.open", mock.mock_open(read_data=code) + ) as mock_open: result = circup.extract_metadata(path) mock_open.assert_called_once_with(path, encoding="utf-8") assert len(result) == 3 @@ -377,7 +384,9 @@ def test_get_bundle_versions(): dirs = (("foo/bar/lib", "", ""),) with mock.patch("circup.ensure_latest_bundle"), mock.patch( "circup.os.walk", return_value=dirs - ) as mock_walk, mock.patch("circup.get_modules", return_value="ok") as mock_gm: + ) as mock_walk, mock.patch( + "circup.get_modules", return_value="ok" + ) as mock_gm: assert circup.get_bundle_versions() == "ok" mock_walk.assert_called_once_with(circup.BUNDLE_DIR.format("py")) mock_gm.assert_called_once_with("foo/bar/lib") @@ -396,16 +405,18 @@ def test_get_circuitpython_version(): device_path = "device" with mock.patch("builtins.open", mock_open): assert circup.get_circuitpython_version(device_path) == "4.1.0" - mock_open.assert_called_once_with(os.path.join(device_path, "boot_out.txt")) + mock_open.assert_called_once_with( + os.path.join(device_path, "boot_out.txt") + ) def test_get_device_versions(): """ Ensure get_modules is called with the path for the attached device. """ - with mock.patch("circup.find_device", return_value="CIRCUITPYTHON"), mock.patch( - "circup.get_modules", return_value="ok" - ) as mock_gm: + with mock.patch( + "circup.find_device", return_value="CIRCUITPYTHON" + ), mock.patch("circup.get_modules", return_value="ok") as mock_gm: assert circup.get_device_versions() == "ok" mock_gm.assert_called_once_with(os.path.join("CIRCUITPYTHON", "lib")) @@ -435,7 +446,9 @@ def test_get_modules_that_are_files(): assert result["local_module"]["path"] == os.path.join( "tests", "local_module.py" ) - assert result["local_module"]["__version__"] == "1.2.3" # from fixture. + assert ( + result["local_module"]["__version__"] == "1.2.3" + ) # from fixture. repo = "https://github.com/adafruit/SomeLibrary.git" # from fixture. assert result["local_module"]["__repo__"] == repo @@ -454,11 +467,15 @@ def test_get_modules_that_are_directories(): "tests/dir_module/my_module.py", "tests/dir_module/__init__.py", ] - with mock.patch("circup.glob.glob", side_effect=[[], [], mods, mod_files, []]): + with mock.patch( + "circup.glob.glob", side_effect=[[], [], mods, mod_files, []] + ): result = circup.get_modules(path) assert len(result) == 1 assert "dir_module" in result - assert result["dir_module"]["path"] == os.path.join("tests", "dir_module", "") + assert result["dir_module"]["path"] == os.path.join( + "tests", "dir_module", "" + ) assert result["dir_module"]["__version__"] == "3.2.1" # from fixture. repo = "https://github.com/adafruit/SomeModule.git" # from fixture. assert result["dir_module"]["__repo__"] == repo @@ -475,11 +492,15 @@ def test_get_modules_that_are_directories_with_no_metadata(): "tests/bad_module/my_module.py", "tests/bad_module/__init__.py", ] - with mock.patch("circup.glob.glob", side_effect=[[], [], mods, mod_files, []]): + with mock.patch( + "circup.glob.glob", side_effect=[[], [], mods, mod_files, []] + ): result = circup.get_modules(path) assert len(result) == 1 assert "bad_module" in result - assert result["bad_module"]["path"] == os.path.join("tests", "bad_module", "") + assert result["bad_module"]["path"] == os.path.join( + "tests", "bad_module", "" + ) assert "__version__" not in result["bad_module"] assert "__repo__" not in result["bad_module"] @@ -510,7 +531,8 @@ def test_ensure_latest_bundle_bad_bundle_data(): ), mock.patch("circup.open"), mock.patch( "circup.get_bundle" ) as mock_gb, mock.patch( - "circup.json.load", side_effect=json.decoder.JSONDecodeError("BANG!", "doc", 1), + "circup.json.load", + side_effect=json.decoder.JSONDecodeError("BANG!", "doc", 1), ), mock.patch( "circup.json.dump" ), mock.patch(