diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 70ade69..761f7a9 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: hooks: - id: reuse - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.4.0 + rev: v5.0.0 hooks: - id: check-yaml - id: end-of-file-fixer diff --git a/adafruit_shell.py b/adafruit_shell.py index 60312f6..d004192 100644 --- a/adafruit_shell.py +++ b/adafruit_shell.py @@ -37,6 +37,23 @@ __version__ = "0.0.0+auto.0" __repo__ = "https://github.com/adafruit/Adafruit_Python_Shell.git" +# This must be by order of release +RASPI_VERSIONS = ( + "wheezy", + "jessie", + "stretch", + "buster", + "bullseye", + "bookworm", + "trixie", +) + +WINDOW_MANAGERS = { + "x11": "W1", + "wayland": "W2", + "labwc": "W3", +} + # pylint: disable=too-many-public-methods class Shell: @@ -555,24 +572,29 @@ def get_raspbian_version(self): """Return a string containing the raspbian version""" if self.get_os() != "Raspbian": return None - raspbian_releases = ( - "bookworm", - "bullseye", - "buster", - "stretch", - "jessie", - "wheezy", - ) if os.path.exists("/etc/os-release"): with open("/etc/os-release", encoding="utf-8") as f: release_file = f.read() if "/sid" in release_file: return "unstable" - for raspbian in raspbian_releases: + for raspbian in RASPI_VERSIONS: if raspbian in release_file: return raspbian return None + def is_minumum_version(self, version): + """Check if the version is at least the specified version""" + # Check that version is a string + if not isinstance(version, str): + raise ValueError("Version must be a string") + # Check that version is in the list of valid versions + if version.lower() not in RASPI_VERSIONS: + raise ValueError("Invalid version") + # Check that the current version is at least the specified version + return RASPI_VERSIONS.index( + self.get_raspbian_version() + ) >= RASPI_VERSIONS.index(version.lower()) + def prompt_reboot(self, default="y", **kwargs): """Prompt the user for a reboot""" if not self.prompt("REBOOT NOW?", default=default, **kwargs): @@ -592,21 +614,64 @@ def check_kernel_update_reboot_required(self): ) self.prompt_reboot() - def check_kernel_userspace_mismatch(self): + def check_kernel_userspace_mismatch(self, attempt_fix=True, fix_with_x11=False): """ Check if the userspace is 64-bit and kernel is 32-bit """ - if self.is_arm64() and platform.architecture()[0] == "32bit": + if self.is_kernel_userspace_mismatched(): print( "Unable to compile driver because kernel space is 64-bit, but user space is 32-bit." ) - if self.is_raspberry_pi_os() and self.prompt( - "Add parameter to /boot/config.txt to use 32-bit kernel?" + config = self.get_boot_config() + if ( + self.is_raspberry_pi_os() + and attempt_fix + and config + and self.prompt(f"Add parameter to {config} to use 32-bit kernel?") ): - self.reconfig("/boot/config.txt", "^.*arm_64bit.*$", "arm_64bit=0") + # Set to use 32-bit kernel + self.reconfig(config, "^.*arm_64bit.*$", "arm_64bit=0") + if fix_with_x11: + self.set_window_manager("x11") self.prompt_reboot() else: - self.bail("Unable to continue while mismatch is present.") + raise RuntimeError("Unable to continue while mismatch is present.") + + def set_window_manager(self, manager): + """ + Call raspi-config to set a new window manager + """ + if not self.is_minumum_version("bullseye"): + return + + if manager.lower() not in WINDOW_MANAGERS: + raise ValueError("Invalid window manager") + + if manager.lower() == "labwc" and not self.exists("/usr/bin/labwc"): + raise RuntimeError("labwc is not installed") + + print(f"Using {manager} as the window manager") + if not self.run_command( + "sudo raspi-config nonint do_wayland " + WINDOW_MANAGERS[manager.lower()] + ): + raise RuntimeError("Unable to change window manager") + + def get_boot_config(self): + """ + Get the location of the boot config file + """ + # check if /boot/firmware/config.txt exists + if self.exists("/boot/firmware/config.txt"): + return "/boot/firmware/config.txt" + if self.exists("/boot/config.txt"): + return "/boot/config.txt" + return None + + def is_kernel_userspace_mismatched(self): + """ + If the userspace 64-bit and kernel is 32-bit? + """ + return self.is_arm64() and platform.architecture()[0] == "32bit" # pylint: enable=invalid-name diff --git a/docs/conf.py b/docs/conf.py index dbeb600..cd1ea74 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -6,6 +6,7 @@ import os import sys +import datetime sys.path.insert(0, os.path.abspath("..")) @@ -16,13 +17,14 @@ # ones. extensions = [ "sphinx.ext.autodoc", + "sphinxcontrib.jquery", "sphinx.ext.intersphinx", "sphinx.ext.napoleon", "sphinx.ext.todo", ] intersphinx_mapping = { - "python": ("https://docs.python.org/3.4", None), + "python": ("https://docs.python.org/3", None), "CircuitPython": ("https://circuitpython.readthedocs.io/en/latest/", None), } @@ -36,7 +38,14 @@ # General information about the project. project = "Adafruit Shell Library" -copyright = "2020 Melissa LeBlanc-Williams" +creation_year = "2020" +current_year = str(datetime.datetime.now().year) +year_duration = ( + current_year + if current_year == creation_year + else creation_year + " - " + current_year +) +copyright = year_duration + " Melissa LeBlanc-Williams" author = "Melissa LeBlanc-Williams" # The version info for the project you're documenting, acts as replacement for @@ -91,19 +100,9 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # -on_rtd = os.environ.get("READTHEDOCS", None) == "True" - -if not on_rtd: # only import and set the theme if we're building docs locally - try: - import sphinx_rtd_theme - - html_theme = "sphinx_rtd_theme" - html_theme_path = [sphinx_rtd_theme.get_html_theme_path(), "."] - except: - html_theme = "default" - html_theme_path = ["."] -else: - html_theme_path = ["."] +import sphinx_rtd_theme + +html_theme = "sphinx_rtd_theme" # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files,