Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS - #38

Merged
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper
May 25, 2026
Merged

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS#38
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper

Conversation

@makermelissa-ai-assistant

Copy link
Copy Markdown
Contributor

Summary

raspi-config is only shipped (and only honored) on Raspberry Pi OS. The installer scripts in Raspberry-Pi-Installer-Scripts shell out to raspi-config nonint ... in a bunch of places (adafruit-pitft.py, raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py, ...) to toggle SPI/I2C, set overscan, change boot behaviour, etc. On non-Pi-OS distros that share the same hardware (DietPi, Ubuntu Server on a Pi, etc.) the binary just isn't there: shell.run_command returns falsy on the missing binary and the script continues, but the tweak silently doesn't happen and the user sees a confusing command not found line.

Change

Adds Shell.run_raspi_config(args, suppress_message=False, return_output=False, run_as_user=None) as a thin wrapper around run_command:

  • Returns immediately (True, or "" when return_output=True) when is_raspberry_pi_os() is False, so callers that ignore the return value short-circuit cleanly and callers that .strip() the output still get a usable string.
  • On Raspberry Pi OS, forwards to run_command("raspi-config nonint " + args, ...) with the same kwargs.

args is the portion after raspi-config nonint — e.g. shell.run_raspi_config("do_spi 0").

Also migrates the existing Shell.set_window_manager() call (which already invokes raspi-config nonint do_wayland … directly) to use the new helper. That gives it the same non-Pi-OS short-circuit and avoids the RuntimeError("Unable to change window manager") it would otherwise raise on hosts where the binary isn't present.

Test plan

Installed the modified package in a venv and exercised run_raspi_config with Shell.run_command monkey-patched to record calls:

ScenarioResultrun_command calls observed
Pi OS, basic call: run_raspi_config('do_spi 0')returns Trueraspi-config nonint do_spi 0
Pi OS, with return_output=True, suppress_message=True: run_raspi_config('get_spi', suppress_message=True, return_output=True)returns subprocess outputraspi-config nonint get_spi with all kwargs forwarded ✓
Non-Pi-OS, basic callreturns Truenone ✓
Non-Pi-OS, return_output=Truereturns '' (so .strip() callers stay happy)none ✓

Follow-up

A companion PR against adafruit/Raspberry-Pi-Installer-Scripts (#384, currently in flight) will switch the call sites in adafruit-pitft.py over to shell.run_raspi_config(...) once this lands. Other scripts in that repo (raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py) can migrate the same way.

@makermelissamakermelissa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

raspi-config is only shipped (and only honored) on Raspberry Pi OS,
so installer scripts that shell out to `raspi-config nonint ...` to
toggle SPI/I2C, set overscan, change boot behaviour, etc. fail
silently on DietPi, Ubuntu, and other Debian-based distros — the
binary isn't there and the configuration tweak it stood for never
happens.
Add a small helper, Shell.run_raspi_config(args, ...), that:
* Returns immediately (True, or "" when return_output=True) when
is_raspberry_pi_os() is False, so callers that ignore the return
value short-circuit cleanly and callers that .strip() the output
still get a usable string.
* On Raspberry Pi OS, forwards to run_command() with the same
suppress_message / return_output / run_as_user kwargs.
Also switch the existing Shell.set_window_manager() raspi-config call
to use the new helper so it behaves the same way on non-Pi-OS hosts
(previously it would have raised RuntimeError after failing to find
the binary).
The intent is for downstream installer scripts (adafruit-pitft.py,
raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py,
pitft-fbcp.py, ...) to switch from `shell.run_command("sudo
raspi-config nonint ...")` to `shell.run_raspi_config(...)` and
inherit the non-Pi-OS skip for free.
@makermelissa
makermelissa merged commit cb02114 into adafruit:mainMay 25, 2026
1 check passed
makermelissa-ai-assistant pushed a commit to makermelissa-ai-assistant/Raspberry-Pi-Installer-Scripts that referenced this pull request May 25, 2026
…it#321)
This repo's Python installer scripts shell out to 'raspi-config
nonint ...' for SPI/I2C toggles, overscan, boot behaviour, fan
service, etc. The raspi-config binary is only shipped (and only
honored) on Raspberry Pi OS; on DietPi, Ubuntu, and other
Debian-based distros the binary is absent and shell.run_command()
returns falsy on the missing executable, so the tweak silently
doesn't happen and the user sees a confusing 'command not found'
line mid-install.
Adafruit_Python_Shell now ships Shell.run_raspi_config(args, ...)
(adafruit/Adafruit_Python_Shell#38) which gates on
shell.is_raspberry_pi_os() and short-circuits cleanly on non-Pi-OS
hosts, returning True (or '' when return_output=True so .strip()
callers stay happy).
Migrate every raspi-config nonint call site in the repo's Python
scripts to the new helper:
* adafruit-pitft.py (6 sites: boot_behaviour, boot_splash,
boot_target, overscan x2)
* raspi-blinka.py (7 sites: i2c, spi, serial_hw, serial,
ssh, camera, disable_raspi_config_at_boot)
* raspi-spi-reassign.py (3 sites incl. get_spi with
return_output=True / .strip())
* joy-bonnet.py (2 sites: i2c, overscan)
* retrogame.py (1 site: i2c)
* pitft-fbcp.py (1 site: spi)
* rtc.py (1 site: i2c)
* adafruit_fanservice.py (1 site: fan -- previously gated only on
is_raspberry_pi(), which is true on
DietPi-on-Pi-hardware)
Closes the underlying 'non-Pi-OS distro support' gap reported in
adafruit#321. (The reporter's specific is_wayland()/loginctl complaint was
already fixed in d14339d, but the broader raspi-config-unavailable
problem on the same distro remained.)
Behavior on Raspberry Pi OS is unchanged. The leading 'sudo' on
the old run_command lines is dropped: all of these installers
already require root via require_root() (or equivalent), so the
inner sudo was redundant. Bash-only scripts in this repo
(pi-eyes.sh, arcade-bonnet.sh, rgb-matrix.sh, retrogame.sh,
spectro.sh) call raspi-config directly and are out of scope here.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@makermelissa-ai-assistant@makermelissa@piclaw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS - #38

Merged
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper
May 25, 2026
Merged

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS#38
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper

Conversation

@makermelissa-ai-assistant

Copy link
Copy Markdown
Contributor

Summary

raspi-config is only shipped (and only honored) on Raspberry Pi OS. The installer scripts in Raspberry-Pi-Installer-Scripts shell out to raspi-config nonint ... in a bunch of places (adafruit-pitft.py, raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py, ...) to toggle SPI/I2C, set overscan, change boot behaviour, etc. On non-Pi-OS distros that share the same hardware (DietPi, Ubuntu Server on a Pi, etc.) the binary just isn't there: shell.run_command returns falsy on the missing binary and the script continues, but the tweak silently doesn't happen and the user sees a confusing command not found line.

Change

Adds Shell.run_raspi_config(args, suppress_message=False, return_output=False, run_as_user=None) as a thin wrapper around run_command:

  • Returns immediately (True, or "" when return_output=True) when is_raspberry_pi_os() is False, so callers that ignore the return value short-circuit cleanly and callers that .strip() the output still get a usable string.
  • On Raspberry Pi OS, forwards to run_command("raspi-config nonint " + args, ...) with the same kwargs.

args is the portion after raspi-config nonint — e.g. shell.run_raspi_config("do_spi 0").

Also migrates the existing Shell.set_window_manager() call (which already invokes raspi-config nonint do_wayland … directly) to use the new helper. That gives it the same non-Pi-OS short-circuit and avoids the RuntimeError("Unable to change window manager") it would otherwise raise on hosts where the binary isn't present.

Test plan

Installed the modified package in a venv and exercised run_raspi_config with Shell.run_command monkey-patched to record calls:

ScenarioResultrun_command calls observed
Pi OS, basic call: run_raspi_config('do_spi 0')returns Trueraspi-config nonint do_spi 0
Pi OS, with return_output=True, suppress_message=True: run_raspi_config('get_spi', suppress_message=True, return_output=True)returns subprocess outputraspi-config nonint get_spi with all kwargs forwarded ✓
Non-Pi-OS, basic callreturns Truenone ✓
Non-Pi-OS, return_output=Truereturns '' (so .strip() callers stay happy)none ✓

Follow-up

A companion PR against adafruit/Raspberry-Pi-Installer-Scripts (#384, currently in flight) will switch the call sites in adafruit-pitft.py over to shell.run_raspi_config(...) once this lands. Other scripts in that repo (raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py) can migrate the same way.

@makermelissamakermelissa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

raspi-config is only shipped (and only honored) on Raspberry Pi OS,
so installer scripts that shell out to `raspi-config nonint ...` to
toggle SPI/I2C, set overscan, change boot behaviour, etc. fail
silently on DietPi, Ubuntu, and other Debian-based distros — the
binary isn't there and the configuration tweak it stood for never
happens.
Add a small helper, Shell.run_raspi_config(args, ...), that:
* Returns immediately (True, or "" when return_output=True) when
is_raspberry_pi_os() is False, so callers that ignore the return
value short-circuit cleanly and callers that .strip() the output
still get a usable string.
* On Raspberry Pi OS, forwards to run_command() with the same
suppress_message / return_output / run_as_user kwargs.
Also switch the existing Shell.set_window_manager() raspi-config call
to use the new helper so it behaves the same way on non-Pi-OS hosts
(previously it would have raised RuntimeError after failing to find
the binary).
The intent is for downstream installer scripts (adafruit-pitft.py,
raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py,
pitft-fbcp.py, ...) to switch from `shell.run_command("sudo
raspi-config nonint ...")` to `shell.run_raspi_config(...)` and
inherit the non-Pi-OS skip for free.
@makermelissa
makermelissa merged commit cb02114 into adafruit:mainMay 25, 2026
1 check passed
makermelissa-ai-assistant pushed a commit to makermelissa-ai-assistant/Raspberry-Pi-Installer-Scripts that referenced this pull request May 25, 2026
…it#321)
This repo's Python installer scripts shell out to 'raspi-config
nonint ...' for SPI/I2C toggles, overscan, boot behaviour, fan
service, etc. The raspi-config binary is only shipped (and only
honored) on Raspberry Pi OS; on DietPi, Ubuntu, and other
Debian-based distros the binary is absent and shell.run_command()
returns falsy on the missing executable, so the tweak silently
doesn't happen and the user sees a confusing 'command not found'
line mid-install.
Adafruit_Python_Shell now ships Shell.run_raspi_config(args, ...)
(adafruit/Adafruit_Python_Shell#38) which gates on
shell.is_raspberry_pi_os() and short-circuits cleanly on non-Pi-OS
hosts, returning True (or '' when return_output=True so .strip()
callers stay happy).
Migrate every raspi-config nonint call site in the repo's Python
scripts to the new helper:
* adafruit-pitft.py (6 sites: boot_behaviour, boot_splash,
boot_target, overscan x2)
* raspi-blinka.py (7 sites: i2c, spi, serial_hw, serial,
ssh, camera, disable_raspi_config_at_boot)
* raspi-spi-reassign.py (3 sites incl. get_spi with
return_output=True / .strip())
* joy-bonnet.py (2 sites: i2c, overscan)
* retrogame.py (1 site: i2c)
* pitft-fbcp.py (1 site: spi)
* rtc.py (1 site: i2c)
* adafruit_fanservice.py (1 site: fan -- previously gated only on
is_raspberry_pi(), which is true on
DietPi-on-Pi-hardware)
Closes the underlying 'non-Pi-OS distro support' gap reported in
adafruit#321. (The reporter's specific is_wayland()/loginctl complaint was
already fixed in d14339d, but the broader raspi-config-unavailable
problem on the same distro remained.)
Behavior on Raspberry Pi OS is unchanged. The leading 'sudo' on
the old run_command lines is dropped: all of these installers
already require root via require_root() (or equivalent), so the
inner sudo was redundant. Bash-only scripts in this repo
(pi-eyes.sh, arcade-bonnet.sh, rgb-matrix.sh, retrogame.sh,
spectro.sh) call raspi-config directly and are out of scope here.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@makermelissa-ai-assistant@makermelissa@piclaw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS - #38

Merged
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper
May 25, 2026
Merged

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS#38
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper

Conversation

@makermelissa-ai-assistant

Copy link
Copy Markdown
Contributor

Summary

raspi-config is only shipped (and only honored) on Raspberry Pi OS. The installer scripts in Raspberry-Pi-Installer-Scripts shell out to raspi-config nonint ... in a bunch of places (adafruit-pitft.py, raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py, ...) to toggle SPI/I2C, set overscan, change boot behaviour, etc. On non-Pi-OS distros that share the same hardware (DietPi, Ubuntu Server on a Pi, etc.) the binary just isn't there: shell.run_command returns falsy on the missing binary and the script continues, but the tweak silently doesn't happen and the user sees a confusing command not found line.

Change

Adds Shell.run_raspi_config(args, suppress_message=False, return_output=False, run_as_user=None) as a thin wrapper around run_command:

  • Returns immediately (True, or "" when return_output=True) when is_raspberry_pi_os() is False, so callers that ignore the return value short-circuit cleanly and callers that .strip() the output still get a usable string.
  • On Raspberry Pi OS, forwards to run_command("raspi-config nonint " + args, ...) with the same kwargs.

args is the portion after raspi-config nonint — e.g. shell.run_raspi_config("do_spi 0").

Also migrates the existing Shell.set_window_manager() call (which already invokes raspi-config nonint do_wayland … directly) to use the new helper. That gives it the same non-Pi-OS short-circuit and avoids the RuntimeError("Unable to change window manager") it would otherwise raise on hosts where the binary isn't present.

Test plan

Installed the modified package in a venv and exercised run_raspi_config with Shell.run_command monkey-patched to record calls:

ScenarioResultrun_command calls observed
Pi OS, basic call: run_raspi_config('do_spi 0')returns Trueraspi-config nonint do_spi 0
Pi OS, with return_output=True, suppress_message=True: run_raspi_config('get_spi', suppress_message=True, return_output=True)returns subprocess outputraspi-config nonint get_spi with all kwargs forwarded ✓
Non-Pi-OS, basic callreturns Truenone ✓
Non-Pi-OS, return_output=Truereturns '' (so .strip() callers stay happy)none ✓

Follow-up

A companion PR against adafruit/Raspberry-Pi-Installer-Scripts (#384, currently in flight) will switch the call sites in adafruit-pitft.py over to shell.run_raspi_config(...) once this lands. Other scripts in that repo (raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py) can migrate the same way.

@makermelissamakermelissa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

raspi-config is only shipped (and only honored) on Raspberry Pi OS,
so installer scripts that shell out to `raspi-config nonint ...` to
toggle SPI/I2C, set overscan, change boot behaviour, etc. fail
silently on DietPi, Ubuntu, and other Debian-based distros — the
binary isn't there and the configuration tweak it stood for never
happens.
Add a small helper, Shell.run_raspi_config(args, ...), that:
* Returns immediately (True, or "" when return_output=True) when
is_raspberry_pi_os() is False, so callers that ignore the return
value short-circuit cleanly and callers that .strip() the output
still get a usable string.
* On Raspberry Pi OS, forwards to run_command() with the same
suppress_message / return_output / run_as_user kwargs.
Also switch the existing Shell.set_window_manager() raspi-config call
to use the new helper so it behaves the same way on non-Pi-OS hosts
(previously it would have raised RuntimeError after failing to find
the binary).
The intent is for downstream installer scripts (adafruit-pitft.py,
raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py,
pitft-fbcp.py, ...) to switch from `shell.run_command("sudo
raspi-config nonint ...")` to `shell.run_raspi_config(...)` and
inherit the non-Pi-OS skip for free.
@makermelissa
makermelissa merged commit cb02114 into adafruit:mainMay 25, 2026
1 check passed
makermelissa-ai-assistant pushed a commit to makermelissa-ai-assistant/Raspberry-Pi-Installer-Scripts that referenced this pull request May 25, 2026
…it#321)
This repo's Python installer scripts shell out to 'raspi-config
nonint ...' for SPI/I2C toggles, overscan, boot behaviour, fan
service, etc. The raspi-config binary is only shipped (and only
honored) on Raspberry Pi OS; on DietPi, Ubuntu, and other
Debian-based distros the binary is absent and shell.run_command()
returns falsy on the missing executable, so the tweak silently
doesn't happen and the user sees a confusing 'command not found'
line mid-install.
Adafruit_Python_Shell now ships Shell.run_raspi_config(args, ...)
(adafruit/Adafruit_Python_Shell#38) which gates on
shell.is_raspberry_pi_os() and short-circuits cleanly on non-Pi-OS
hosts, returning True (or '' when return_output=True so .strip()
callers stay happy).
Migrate every raspi-config nonint call site in the repo's Python
scripts to the new helper:
* adafruit-pitft.py (6 sites: boot_behaviour, boot_splash,
boot_target, overscan x2)
* raspi-blinka.py (7 sites: i2c, spi, serial_hw, serial,
ssh, camera, disable_raspi_config_at_boot)
* raspi-spi-reassign.py (3 sites incl. get_spi with
return_output=True / .strip())
* joy-bonnet.py (2 sites: i2c, overscan)
* retrogame.py (1 site: i2c)
* pitft-fbcp.py (1 site: spi)
* rtc.py (1 site: i2c)
* adafruit_fanservice.py (1 site: fan -- previously gated only on
is_raspberry_pi(), which is true on
DietPi-on-Pi-hardware)
Closes the underlying 'non-Pi-OS distro support' gap reported in
adafruit#321. (The reporter's specific is_wayland()/loginctl complaint was
already fixed in d14339d, but the broader raspi-config-unavailable
problem on the same distro remained.)
Behavior on Raspberry Pi OS is unchanged. The leading 'sudo' on
the old run_command lines is dropped: all of these installers
already require root via require_root() (or equivalent), so the
inner sudo was redundant. Bash-only scripts in this repo
(pi-eyes.sh, arcade-bonnet.sh, rgb-matrix.sh, retrogame.sh,
spectro.sh) call raspi-config directly and are out of scope here.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@makermelissa-ai-assistant@makermelissa@piclaw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS - #38

Merged
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper
May 25, 2026
Merged

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS#38
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper

Conversation

@makermelissa-ai-assistant

Copy link
Copy Markdown
Contributor

Summary

raspi-config is only shipped (and only honored) on Raspberry Pi OS. The installer scripts in Raspberry-Pi-Installer-Scripts shell out to raspi-config nonint ... in a bunch of places (adafruit-pitft.py, raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py, ...) to toggle SPI/I2C, set overscan, change boot behaviour, etc. On non-Pi-OS distros that share the same hardware (DietPi, Ubuntu Server on a Pi, etc.) the binary just isn't there: shell.run_command returns falsy on the missing binary and the script continues, but the tweak silently doesn't happen and the user sees a confusing command not found line.

Change

Adds Shell.run_raspi_config(args, suppress_message=False, return_output=False, run_as_user=None) as a thin wrapper around run_command:

  • Returns immediately (True, or "" when return_output=True) when is_raspberry_pi_os() is False, so callers that ignore the return value short-circuit cleanly and callers that .strip() the output still get a usable string.
  • On Raspberry Pi OS, forwards to run_command("raspi-config nonint " + args, ...) with the same kwargs.

args is the portion after raspi-config nonint — e.g. shell.run_raspi_config("do_spi 0").

Also migrates the existing Shell.set_window_manager() call (which already invokes raspi-config nonint do_wayland … directly) to use the new helper. That gives it the same non-Pi-OS short-circuit and avoids the RuntimeError("Unable to change window manager") it would otherwise raise on hosts where the binary isn't present.

Test plan

Installed the modified package in a venv and exercised run_raspi_config with Shell.run_command monkey-patched to record calls:

ScenarioResultrun_command calls observed
Pi OS, basic call: run_raspi_config('do_spi 0')returns Trueraspi-config nonint do_spi 0
Pi OS, with return_output=True, suppress_message=True: run_raspi_config('get_spi', suppress_message=True, return_output=True)returns subprocess outputraspi-config nonint get_spi with all kwargs forwarded ✓
Non-Pi-OS, basic callreturns Truenone ✓
Non-Pi-OS, return_output=Truereturns '' (so .strip() callers stay happy)none ✓

Follow-up

A companion PR against adafruit/Raspberry-Pi-Installer-Scripts (#384, currently in flight) will switch the call sites in adafruit-pitft.py over to shell.run_raspi_config(...) once this lands. Other scripts in that repo (raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py) can migrate the same way.

@makermelissamakermelissa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

raspi-config is only shipped (and only honored) on Raspberry Pi OS,
so installer scripts that shell out to `raspi-config nonint ...` to
toggle SPI/I2C, set overscan, change boot behaviour, etc. fail
silently on DietPi, Ubuntu, and other Debian-based distros — the
binary isn't there and the configuration tweak it stood for never
happens.
Add a small helper, Shell.run_raspi_config(args, ...), that:
* Returns immediately (True, or "" when return_output=True) when
is_raspberry_pi_os() is False, so callers that ignore the return
value short-circuit cleanly and callers that .strip() the output
still get a usable string.
* On Raspberry Pi OS, forwards to run_command() with the same
suppress_message / return_output / run_as_user kwargs.
Also switch the existing Shell.set_window_manager() raspi-config call
to use the new helper so it behaves the same way on non-Pi-OS hosts
(previously it would have raised RuntimeError after failing to find
the binary).
The intent is for downstream installer scripts (adafruit-pitft.py,
raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py,
pitft-fbcp.py, ...) to switch from `shell.run_command("sudo
raspi-config nonint ...")` to `shell.run_raspi_config(...)` and
inherit the non-Pi-OS skip for free.
@makermelissa
makermelissa merged commit cb02114 into adafruit:mainMay 25, 2026
1 check passed
makermelissa-ai-assistant pushed a commit to makermelissa-ai-assistant/Raspberry-Pi-Installer-Scripts that referenced this pull request May 25, 2026
…it#321)
This repo's Python installer scripts shell out to 'raspi-config
nonint ...' for SPI/I2C toggles, overscan, boot behaviour, fan
service, etc. The raspi-config binary is only shipped (and only
honored) on Raspberry Pi OS; on DietPi, Ubuntu, and other
Debian-based distros the binary is absent and shell.run_command()
returns falsy on the missing executable, so the tweak silently
doesn't happen and the user sees a confusing 'command not found'
line mid-install.
Adafruit_Python_Shell now ships Shell.run_raspi_config(args, ...)
(adafruit/Adafruit_Python_Shell#38) which gates on
shell.is_raspberry_pi_os() and short-circuits cleanly on non-Pi-OS
hosts, returning True (or '' when return_output=True so .strip()
callers stay happy).
Migrate every raspi-config nonint call site in the repo's Python
scripts to the new helper:
* adafruit-pitft.py (6 sites: boot_behaviour, boot_splash,
boot_target, overscan x2)
* raspi-blinka.py (7 sites: i2c, spi, serial_hw, serial,
ssh, camera, disable_raspi_config_at_boot)
* raspi-spi-reassign.py (3 sites incl. get_spi with
return_output=True / .strip())
* joy-bonnet.py (2 sites: i2c, overscan)
* retrogame.py (1 site: i2c)
* pitft-fbcp.py (1 site: spi)
* rtc.py (1 site: i2c)
* adafruit_fanservice.py (1 site: fan -- previously gated only on
is_raspberry_pi(), which is true on
DietPi-on-Pi-hardware)
Closes the underlying 'non-Pi-OS distro support' gap reported in
adafruit#321. (The reporter's specific is_wayland()/loginctl complaint was
already fixed in d14339d, but the broader raspi-config-unavailable
problem on the same distro remained.)
Behavior on Raspberry Pi OS is unchanged. The leading 'sudo' on
the old run_command lines is dropped: all of these installers
already require root via require_root() (or equivalent), so the
inner sudo was redundant. Bash-only scripts in this repo
(pi-eyes.sh, arcade-bonnet.sh, rgb-matrix.sh, retrogame.sh,
spectro.sh) call raspi-config directly and are out of scope here.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@makermelissa-ai-assistant@makermelissa@piclaw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS - #38

Merged
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper
May 25, 2026
Merged

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS#38
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper

Conversation

@makermelissa-ai-assistant

Copy link
Copy Markdown
Contributor

Summary

raspi-config is only shipped (and only honored) on Raspberry Pi OS. The installer scripts in Raspberry-Pi-Installer-Scripts shell out to raspi-config nonint ... in a bunch of places (adafruit-pitft.py, raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py, ...) to toggle SPI/I2C, set overscan, change boot behaviour, etc. On non-Pi-OS distros that share the same hardware (DietPi, Ubuntu Server on a Pi, etc.) the binary just isn't there: shell.run_command returns falsy on the missing binary and the script continues, but the tweak silently doesn't happen and the user sees a confusing command not found line.

Change

Adds Shell.run_raspi_config(args, suppress_message=False, return_output=False, run_as_user=None) as a thin wrapper around run_command:

  • Returns immediately (True, or "" when return_output=True) when is_raspberry_pi_os() is False, so callers that ignore the return value short-circuit cleanly and callers that .strip() the output still get a usable string.
  • On Raspberry Pi OS, forwards to run_command("raspi-config nonint " + args, ...) with the same kwargs.

args is the portion after raspi-config nonint — e.g. shell.run_raspi_config("do_spi 0").

Also migrates the existing Shell.set_window_manager() call (which already invokes raspi-config nonint do_wayland … directly) to use the new helper. That gives it the same non-Pi-OS short-circuit and avoids the RuntimeError("Unable to change window manager") it would otherwise raise on hosts where the binary isn't present.

Test plan

Installed the modified package in a venv and exercised run_raspi_config with Shell.run_command monkey-patched to record calls:

ScenarioResultrun_command calls observed
Pi OS, basic call: run_raspi_config('do_spi 0')returns Trueraspi-config nonint do_spi 0
Pi OS, with return_output=True, suppress_message=True: run_raspi_config('get_spi', suppress_message=True, return_output=True)returns subprocess outputraspi-config nonint get_spi with all kwargs forwarded ✓
Non-Pi-OS, basic callreturns Truenone ✓
Non-Pi-OS, return_output=Truereturns '' (so .strip() callers stay happy)none ✓

Follow-up

A companion PR against adafruit/Raspberry-Pi-Installer-Scripts (#384, currently in flight) will switch the call sites in adafruit-pitft.py over to shell.run_raspi_config(...) once this lands. Other scripts in that repo (raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py) can migrate the same way.

@makermelissamakermelissa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

raspi-config is only shipped (and only honored) on Raspberry Pi OS,
so installer scripts that shell out to `raspi-config nonint ...` to
toggle SPI/I2C, set overscan, change boot behaviour, etc. fail
silently on DietPi, Ubuntu, and other Debian-based distros — the
binary isn't there and the configuration tweak it stood for never
happens.
Add a small helper, Shell.run_raspi_config(args, ...), that:
* Returns immediately (True, or "" when return_output=True) when
is_raspberry_pi_os() is False, so callers that ignore the return
value short-circuit cleanly and callers that .strip() the output
still get a usable string.
* On Raspberry Pi OS, forwards to run_command() with the same
suppress_message / return_output / run_as_user kwargs.
Also switch the existing Shell.set_window_manager() raspi-config call
to use the new helper so it behaves the same way on non-Pi-OS hosts
(previously it would have raised RuntimeError after failing to find
the binary).
The intent is for downstream installer scripts (adafruit-pitft.py,
raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py,
pitft-fbcp.py, ...) to switch from `shell.run_command("sudo
raspi-config nonint ...")` to `shell.run_raspi_config(...)` and
inherit the non-Pi-OS skip for free.
@makermelissa
makermelissa merged commit cb02114 into adafruit:mainMay 25, 2026
1 check passed
makermelissa-ai-assistant pushed a commit to makermelissa-ai-assistant/Raspberry-Pi-Installer-Scripts that referenced this pull request May 25, 2026
…it#321)
This repo's Python installer scripts shell out to 'raspi-config
nonint ...' for SPI/I2C toggles, overscan, boot behaviour, fan
service, etc. The raspi-config binary is only shipped (and only
honored) on Raspberry Pi OS; on DietPi, Ubuntu, and other
Debian-based distros the binary is absent and shell.run_command()
returns falsy on the missing executable, so the tweak silently
doesn't happen and the user sees a confusing 'command not found'
line mid-install.
Adafruit_Python_Shell now ships Shell.run_raspi_config(args, ...)
(adafruit/Adafruit_Python_Shell#38) which gates on
shell.is_raspberry_pi_os() and short-circuits cleanly on non-Pi-OS
hosts, returning True (or '' when return_output=True so .strip()
callers stay happy).
Migrate every raspi-config nonint call site in the repo's Python
scripts to the new helper:
* adafruit-pitft.py (6 sites: boot_behaviour, boot_splash,
boot_target, overscan x2)
* raspi-blinka.py (7 sites: i2c, spi, serial_hw, serial,
ssh, camera, disable_raspi_config_at_boot)
* raspi-spi-reassign.py (3 sites incl. get_spi with
return_output=True / .strip())
* joy-bonnet.py (2 sites: i2c, overscan)
* retrogame.py (1 site: i2c)
* pitft-fbcp.py (1 site: spi)
* rtc.py (1 site: i2c)
* adafruit_fanservice.py (1 site: fan -- previously gated only on
is_raspberry_pi(), which is true on
DietPi-on-Pi-hardware)
Closes the underlying 'non-Pi-OS distro support' gap reported in
adafruit#321. (The reporter's specific is_wayland()/loginctl complaint was
already fixed in d14339d, but the broader raspi-config-unavailable
problem on the same distro remained.)
Behavior on Raspberry Pi OS is unchanged. The leading 'sudo' on
the old run_command lines is dropped: all of these installers
already require root via require_root() (or equivalent), so the
inner sudo was redundant. Bash-only scripts in this repo
(pi-eyes.sh, arcade-bonnet.sh, rgb-matrix.sh, retrogame.sh,
spectro.sh) call raspi-config directly and are out of scope here.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@makermelissa-ai-assistant@makermelissa@piclaw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS - #38

Merged
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper
May 25, 2026
Merged

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS#38
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper

Conversation

@makermelissa-ai-assistant

Copy link
Copy Markdown
Contributor

Summary

raspi-config is only shipped (and only honored) on Raspberry Pi OS. The installer scripts in Raspberry-Pi-Installer-Scripts shell out to raspi-config nonint ... in a bunch of places (adafruit-pitft.py, raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py, ...) to toggle SPI/I2C, set overscan, change boot behaviour, etc. On non-Pi-OS distros that share the same hardware (DietPi, Ubuntu Server on a Pi, etc.) the binary just isn't there: shell.run_command returns falsy on the missing binary and the script continues, but the tweak silently doesn't happen and the user sees a confusing command not found line.

Change

Adds Shell.run_raspi_config(args, suppress_message=False, return_output=False, run_as_user=None) as a thin wrapper around run_command:

  • Returns immediately (True, or "" when return_output=True) when is_raspberry_pi_os() is False, so callers that ignore the return value short-circuit cleanly and callers that .strip() the output still get a usable string.
  • On Raspberry Pi OS, forwards to run_command("raspi-config nonint " + args, ...) with the same kwargs.

args is the portion after raspi-config nonint — e.g. shell.run_raspi_config("do_spi 0").

Also migrates the existing Shell.set_window_manager() call (which already invokes raspi-config nonint do_wayland … directly) to use the new helper. That gives it the same non-Pi-OS short-circuit and avoids the RuntimeError("Unable to change window manager") it would otherwise raise on hosts where the binary isn't present.

Test plan

Installed the modified package in a venv and exercised run_raspi_config with Shell.run_command monkey-patched to record calls:

ScenarioResultrun_command calls observed
Pi OS, basic call: run_raspi_config('do_spi 0')returns Trueraspi-config nonint do_spi 0
Pi OS, with return_output=True, suppress_message=True: run_raspi_config('get_spi', suppress_message=True, return_output=True)returns subprocess outputraspi-config nonint get_spi with all kwargs forwarded ✓
Non-Pi-OS, basic callreturns Truenone ✓
Non-Pi-OS, return_output=Truereturns '' (so .strip() callers stay happy)none ✓

Follow-up

A companion PR against adafruit/Raspberry-Pi-Installer-Scripts (#384, currently in flight) will switch the call sites in adafruit-pitft.py over to shell.run_raspi_config(...) once this lands. Other scripts in that repo (raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py) can migrate the same way.

@makermelissamakermelissa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

raspi-config is only shipped (and only honored) on Raspberry Pi OS,
so installer scripts that shell out to `raspi-config nonint ...` to
toggle SPI/I2C, set overscan, change boot behaviour, etc. fail
silently on DietPi, Ubuntu, and other Debian-based distros — the
binary isn't there and the configuration tweak it stood for never
happens.
Add a small helper, Shell.run_raspi_config(args, ...), that:
* Returns immediately (True, or "" when return_output=True) when
is_raspberry_pi_os() is False, so callers that ignore the return
value short-circuit cleanly and callers that .strip() the output
still get a usable string.
* On Raspberry Pi OS, forwards to run_command() with the same
suppress_message / return_output / run_as_user kwargs.
Also switch the existing Shell.set_window_manager() raspi-config call
to use the new helper so it behaves the same way on non-Pi-OS hosts
(previously it would have raised RuntimeError after failing to find
the binary).
The intent is for downstream installer scripts (adafruit-pitft.py,
raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py,
pitft-fbcp.py, ...) to switch from `shell.run_command("sudo
raspi-config nonint ...")` to `shell.run_raspi_config(...)` and
inherit the non-Pi-OS skip for free.
@makermelissa
makermelissa merged commit cb02114 into adafruit:mainMay 25, 2026
1 check passed
makermelissa-ai-assistant pushed a commit to makermelissa-ai-assistant/Raspberry-Pi-Installer-Scripts that referenced this pull request May 25, 2026
…it#321)
This repo's Python installer scripts shell out to 'raspi-config
nonint ...' for SPI/I2C toggles, overscan, boot behaviour, fan
service, etc. The raspi-config binary is only shipped (and only
honored) on Raspberry Pi OS; on DietPi, Ubuntu, and other
Debian-based distros the binary is absent and shell.run_command()
returns falsy on the missing executable, so the tweak silently
doesn't happen and the user sees a confusing 'command not found'
line mid-install.
Adafruit_Python_Shell now ships Shell.run_raspi_config(args, ...)
(adafruit/Adafruit_Python_Shell#38) which gates on
shell.is_raspberry_pi_os() and short-circuits cleanly on non-Pi-OS
hosts, returning True (or '' when return_output=True so .strip()
callers stay happy).
Migrate every raspi-config nonint call site in the repo's Python
scripts to the new helper:
* adafruit-pitft.py (6 sites: boot_behaviour, boot_splash,
boot_target, overscan x2)
* raspi-blinka.py (7 sites: i2c, spi, serial_hw, serial,
ssh, camera, disable_raspi_config_at_boot)
* raspi-spi-reassign.py (3 sites incl. get_spi with
return_output=True / .strip())
* joy-bonnet.py (2 sites: i2c, overscan)
* retrogame.py (1 site: i2c)
* pitft-fbcp.py (1 site: spi)
* rtc.py (1 site: i2c)
* adafruit_fanservice.py (1 site: fan -- previously gated only on
is_raspberry_pi(), which is true on
DietPi-on-Pi-hardware)
Closes the underlying 'non-Pi-OS distro support' gap reported in
adafruit#321. (The reporter's specific is_wayland()/loginctl complaint was
already fixed in d14339d, but the broader raspi-config-unavailable
problem on the same distro remained.)
Behavior on Raspberry Pi OS is unchanged. The leading 'sudo' on
the old run_command lines is dropped: all of these installers
already require root via require_root() (or equivalent), so the
inner sudo was redundant. Bash-only scripts in this repo
(pi-eyes.sh, arcade-bonnet.sh, rgb-matrix.sh, retrogame.sh,
spectro.sh) call raspi-config directly and are out of scope here.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@makermelissa-ai-assistant@makermelissa@piclaw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS - #38

Merged
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper
May 25, 2026
Merged

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS#38
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper

Conversation

@makermelissa-ai-assistant

Copy link
Copy Markdown
Contributor

Summary

raspi-config is only shipped (and only honored) on Raspberry Pi OS. The installer scripts in Raspberry-Pi-Installer-Scripts shell out to raspi-config nonint ... in a bunch of places (adafruit-pitft.py, raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py, ...) to toggle SPI/I2C, set overscan, change boot behaviour, etc. On non-Pi-OS distros that share the same hardware (DietPi, Ubuntu Server on a Pi, etc.) the binary just isn't there: shell.run_command returns falsy on the missing binary and the script continues, but the tweak silently doesn't happen and the user sees a confusing command not found line.

Change

Adds Shell.run_raspi_config(args, suppress_message=False, return_output=False, run_as_user=None) as a thin wrapper around run_command:

  • Returns immediately (True, or "" when return_output=True) when is_raspberry_pi_os() is False, so callers that ignore the return value short-circuit cleanly and callers that .strip() the output still get a usable string.
  • On Raspberry Pi OS, forwards to run_command("raspi-config nonint " + args, ...) with the same kwargs.

args is the portion after raspi-config nonint — e.g. shell.run_raspi_config("do_spi 0").

Also migrates the existing Shell.set_window_manager() call (which already invokes raspi-config nonint do_wayland … directly) to use the new helper. That gives it the same non-Pi-OS short-circuit and avoids the RuntimeError("Unable to change window manager") it would otherwise raise on hosts where the binary isn't present.

Test plan

Installed the modified package in a venv and exercised run_raspi_config with Shell.run_command monkey-patched to record calls:

ScenarioResultrun_command calls observed
Pi OS, basic call: run_raspi_config('do_spi 0')returns Trueraspi-config nonint do_spi 0
Pi OS, with return_output=True, suppress_message=True: run_raspi_config('get_spi', suppress_message=True, return_output=True)returns subprocess outputraspi-config nonint get_spi with all kwargs forwarded ✓
Non-Pi-OS, basic callreturns Truenone ✓
Non-Pi-OS, return_output=Truereturns '' (so .strip() callers stay happy)none ✓

Follow-up

A companion PR against adafruit/Raspberry-Pi-Installer-Scripts (#384, currently in flight) will switch the call sites in adafruit-pitft.py over to shell.run_raspi_config(...) once this lands. Other scripts in that repo (raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py) can migrate the same way.

@makermelissamakermelissa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

raspi-config is only shipped (and only honored) on Raspberry Pi OS,
so installer scripts that shell out to `raspi-config nonint ...` to
toggle SPI/I2C, set overscan, change boot behaviour, etc. fail
silently on DietPi, Ubuntu, and other Debian-based distros — the
binary isn't there and the configuration tweak it stood for never
happens.
Add a small helper, Shell.run_raspi_config(args, ...), that:
* Returns immediately (True, or "" when return_output=True) when
is_raspberry_pi_os() is False, so callers that ignore the return
value short-circuit cleanly and callers that .strip() the output
still get a usable string.
* On Raspberry Pi OS, forwards to run_command() with the same
suppress_message / return_output / run_as_user kwargs.
Also switch the existing Shell.set_window_manager() raspi-config call
to use the new helper so it behaves the same way on non-Pi-OS hosts
(previously it would have raised RuntimeError after failing to find
the binary).
The intent is for downstream installer scripts (adafruit-pitft.py,
raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py,
pitft-fbcp.py, ...) to switch from `shell.run_command("sudo
raspi-config nonint ...")` to `shell.run_raspi_config(...)` and
inherit the non-Pi-OS skip for free.
@makermelissa
makermelissa merged commit cb02114 into adafruit:mainMay 25, 2026
1 check passed
makermelissa-ai-assistant pushed a commit to makermelissa-ai-assistant/Raspberry-Pi-Installer-Scripts that referenced this pull request May 25, 2026
…it#321)
This repo's Python installer scripts shell out to 'raspi-config
nonint ...' for SPI/I2C toggles, overscan, boot behaviour, fan
service, etc. The raspi-config binary is only shipped (and only
honored) on Raspberry Pi OS; on DietPi, Ubuntu, and other
Debian-based distros the binary is absent and shell.run_command()
returns falsy on the missing executable, so the tweak silently
doesn't happen and the user sees a confusing 'command not found'
line mid-install.
Adafruit_Python_Shell now ships Shell.run_raspi_config(args, ...)
(adafruit/Adafruit_Python_Shell#38) which gates on
shell.is_raspberry_pi_os() and short-circuits cleanly on non-Pi-OS
hosts, returning True (or '' when return_output=True so .strip()
callers stay happy).
Migrate every raspi-config nonint call site in the repo's Python
scripts to the new helper:
* adafruit-pitft.py (6 sites: boot_behaviour, boot_splash,
boot_target, overscan x2)
* raspi-blinka.py (7 sites: i2c, spi, serial_hw, serial,
ssh, camera, disable_raspi_config_at_boot)
* raspi-spi-reassign.py (3 sites incl. get_spi with
return_output=True / .strip())
* joy-bonnet.py (2 sites: i2c, overscan)
* retrogame.py (1 site: i2c)
* pitft-fbcp.py (1 site: spi)
* rtc.py (1 site: i2c)
* adafruit_fanservice.py (1 site: fan -- previously gated only on
is_raspberry_pi(), which is true on
DietPi-on-Pi-hardware)
Closes the underlying 'non-Pi-OS distro support' gap reported in
adafruit#321. (The reporter's specific is_wayland()/loginctl complaint was
already fixed in d14339d, but the broader raspi-config-unavailable
problem on the same distro remained.)
Behavior on Raspberry Pi OS is unchanged. The leading 'sudo' on
the old run_command lines is dropped: all of these installers
already require root via require_root() (or equivalent), so the
inner sudo was redundant. Bash-only scripts in this repo
(pi-eyes.sh, arcade-bonnet.sh, rgb-matrix.sh, retrogame.sh,
spectro.sh) call raspi-config directly and are out of scope here.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@makermelissa-ai-assistant@makermelissa@piclaw
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS - #38

Merged
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper
May 25, 2026
Merged

Add Shell.run_raspi_config() that no-ops on non-Raspberry-Pi-OS#38
makermelissa merged 1 commit into
adafruit:mainfrom
makermelissa-ai-assistant:add-run-raspi-config-helper

Conversation

@makermelissa-ai-assistant

Copy link
Copy Markdown
Contributor

Summary

raspi-config is only shipped (and only honored) on Raspberry Pi OS. The installer scripts in Raspberry-Pi-Installer-Scripts shell out to raspi-config nonint ... in a bunch of places (adafruit-pitft.py, raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py, ...) to toggle SPI/I2C, set overscan, change boot behaviour, etc. On non-Pi-OS distros that share the same hardware (DietPi, Ubuntu Server on a Pi, etc.) the binary just isn't there: shell.run_command returns falsy on the missing binary and the script continues, but the tweak silently doesn't happen and the user sees a confusing command not found line.

Change

Adds Shell.run_raspi_config(args, suppress_message=False, return_output=False, run_as_user=None) as a thin wrapper around run_command:

  • Returns immediately (True, or "" when return_output=True) when is_raspberry_pi_os() is False, so callers that ignore the return value short-circuit cleanly and callers that .strip() the output still get a usable string.
  • On Raspberry Pi OS, forwards to run_command("raspi-config nonint " + args, ...) with the same kwargs.

args is the portion after raspi-config nonint — e.g. shell.run_raspi_config("do_spi 0").

Also migrates the existing Shell.set_window_manager() call (which already invokes raspi-config nonint do_wayland … directly) to use the new helper. That gives it the same non-Pi-OS short-circuit and avoids the RuntimeError("Unable to change window manager") it would otherwise raise on hosts where the binary isn't present.

Test plan

Installed the modified package in a venv and exercised run_raspi_config with Shell.run_command monkey-patched to record calls:

ScenarioResultrun_command calls observed
Pi OS, basic call: run_raspi_config('do_spi 0')returns Trueraspi-config nonint do_spi 0
Pi OS, with return_output=True, suppress_message=True: run_raspi_config('get_spi', suppress_message=True, return_output=True)returns subprocess outputraspi-config nonint get_spi with all kwargs forwarded ✓
Non-Pi-OS, basic callreturns Truenone ✓
Non-Pi-OS, return_output=Truereturns '' (so .strip() callers stay happy)none ✓

Follow-up

A companion PR against adafruit/Raspberry-Pi-Installer-Scripts (#384, currently in flight) will switch the call sites in adafruit-pitft.py over to shell.run_raspi_config(...) once this lands. Other scripts in that repo (raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py, pitft-fbcp.py) can migrate the same way.

@makermelissamakermelissa left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good.

raspi-config is only shipped (and only honored) on Raspberry Pi OS,
so installer scripts that shell out to `raspi-config nonint ...` to
toggle SPI/I2C, set overscan, change boot behaviour, etc. fail
silently on DietPi, Ubuntu, and other Debian-based distros — the
binary isn't there and the configuration tweak it stood for never
happens.
Add a small helper, Shell.run_raspi_config(args, ...), that:
* Returns immediately (True, or "" when return_output=True) when
is_raspberry_pi_os() is False, so callers that ignore the return
value short-circuit cleanly and callers that .strip() the output
still get a usable string.
* On Raspberry Pi OS, forwards to run_command() with the same
suppress_message / return_output / run_as_user kwargs.
Also switch the existing Shell.set_window_manager() raspi-config call
to use the new helper so it behaves the same way on non-Pi-OS hosts
(previously it would have raised RuntimeError after failing to find
the binary).
The intent is for downstream installer scripts (adafruit-pitft.py,
raspi-blinka.py, raspi-spi-reassign.py, joy-bonnet.py, retrogame.py,
pitft-fbcp.py, ...) to switch from `shell.run_command("sudo
raspi-config nonint ...")` to `shell.run_raspi_config(...)` and
inherit the non-Pi-OS skip for free.
@makermelissa
makermelissa merged commit cb02114 into adafruit:mainMay 25, 2026
1 check passed
makermelissa-ai-assistant pushed a commit to makermelissa-ai-assistant/Raspberry-Pi-Installer-Scripts that referenced this pull request May 25, 2026
…it#321)
This repo's Python installer scripts shell out to 'raspi-config
nonint ...' for SPI/I2C toggles, overscan, boot behaviour, fan
service, etc. The raspi-config binary is only shipped (and only
honored) on Raspberry Pi OS; on DietPi, Ubuntu, and other
Debian-based distros the binary is absent and shell.run_command()
returns falsy on the missing executable, so the tweak silently
doesn't happen and the user sees a confusing 'command not found'
line mid-install.
Adafruit_Python_Shell now ships Shell.run_raspi_config(args, ...)
(adafruit/Adafruit_Python_Shell#38) which gates on
shell.is_raspberry_pi_os() and short-circuits cleanly on non-Pi-OS
hosts, returning True (or '' when return_output=True so .strip()
callers stay happy).
Migrate every raspi-config nonint call site in the repo's Python
scripts to the new helper:
* adafruit-pitft.py (6 sites: boot_behaviour, boot_splash,
boot_target, overscan x2)
* raspi-blinka.py (7 sites: i2c, spi, serial_hw, serial,
ssh, camera, disable_raspi_config_at_boot)
* raspi-spi-reassign.py (3 sites incl. get_spi with
return_output=True / .strip())
* joy-bonnet.py (2 sites: i2c, overscan)
* retrogame.py (1 site: i2c)
* pitft-fbcp.py (1 site: spi)
* rtc.py (1 site: i2c)
* adafruit_fanservice.py (1 site: fan -- previously gated only on
is_raspberry_pi(), which is true on
DietPi-on-Pi-hardware)
Closes the underlying 'non-Pi-OS distro support' gap reported in
adafruit#321. (The reporter's specific is_wayland()/loginctl complaint was
already fixed in d14339d, but the broader raspi-config-unavailable
problem on the same distro remained.)
Behavior on Raspberry Pi OS is unchanged. The leading 'sudo' on
the old run_command lines is dropped: all of these installers
already require root via require_root() (or equivalent), so the
inner sudo was redundant. Bash-only scripts in this repo
(pi-eyes.sh, arcade-bonnet.sh, rgb-matrix.sh, retrogame.sh,
spectro.sh) call raspi-config directly and are out of scope here.
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@makermelissa-ai-assistant@makermelissa@piclaw