feat: Add in-place upgrade suggestion to colab update (#36)
print an additional hint suggesting `colab update --install` when supported.
Seth Troisi committed
Jun 2, 2026 at 09:46 UTC
f4ef6a6727c464a011e44d80b9b25986ad977351
3 files changed
+41
-2
docs/04_automation_and_utility.md
+5
-2
@@ -1,5 +1,6 @@
1
---
2
log:
3
+2026-06-01: Improved `colab update` output. On Linux platforms, an additional message is shown recommending `colab update --install` to upgrade in place, positioned above the standard `pip`/`uv` installation command.
4
2026-05-27: Refactored `colab README` and `colab AGENT` to bundle `README.md` and `AGENTS.md` via Hatchling's `force-include` and read them using `importlib.resources` instead of `importlib.metadata`. `colab AGENT` now correctly prints `AGENTS.md`.
5
2026-05-27: Extended `colab update --install` to detect if the CLI was installed via `uv tool install` (by checking if `sys.executable` contains `/uv/`) and if so, use `uv tool install -U google-colab-cli` to upgrade.
6
2026-05-27: Updated auto-update upgrade hint to recommend `pip install --upgrade google-colab-cli` instead of `colab`, aligning with the PyPI package name.
@@ -185,8 +186,10 @@ remediation guidance) rather than silently after ~1 minute via the daemon.
186
the cache.
187
- **Notification**: If a new version is found, a non-intrusive message is
188
printed to the console with a `Run 'pip install --upgrade google-colab-cli' to
188
- update.` hint. The cached banner shown between fetches uses the generic
189
- `Run 'colab update' to update.` hint.
189
+ update.` hint. On Linux platforms where `--install` self-update is supported,
190
+ an additional hint `You can run 'colab update --install' to upgrade in place.`
191
+ is displayed above the pip/uv install command. The cached banner shown between
192
+ fetches uses the generic `Run 'colab update' to update.` hint.
193
- **Self-install (`--install`)**: An opt-in `--install` flag (default
194
`False`) makes `colab update` upgrade the CLI in place (**Linux only**).
195
It detects how the CLI was installed:
src/colab_cli/auto_update.py
+2
@@ -113,6 +113,8 @@ def announce_upgrade(
113
typer.echo(
114
f"\n[colab] A new version of Colab CLI is available: {latest} (current: {current})"
115
)
116
+ if platform.system() == "Linux" and ("pip" in install_cmd or "uv" in install_cmd):
117
+ typer.echo("[colab] You can run 'colab update --install' to upgrade in place.")
118
typer.echo(f"[colab] Run '{install_cmd}' to update.")
119
if show_disable_hint:
120
typer.echo(
tests/test_update.py
+34
@@ -129,8 +129,17 @@ def test_pypi_upgrade_uses_pip_hint(mocker, app_version, fake_settings, mock_pyp
129
result = runner.invoke(app, ["update"])
130
assert result.exit_code == 0
131
assert "available: 1.1.0 (current: 1.0.0)" in result.output
132
+ assert "You can run 'colab update --install' to upgrade in place." in result.output
133
assert "Run 'pip install --upgrade google-colab-cli' to update." in result.output
134
135
+ idx_install = result.output.find(
136
+ "You can run 'colab update --install' to upgrade in place."
137
+ )
138
+ idx_pip = result.output.find(
139
+ "Run 'pip install --upgrade google-colab-cli' to update."
140
+ )
141
+ assert idx_install < idx_pip
142
+
143
144
def test_pypi_upgrade_uses_uv_hint(mocker, app_version, fake_settings, mock_pypi):
145
app_version("1.0.0")
@@ -144,8 +153,33 @@ def test_pypi_upgrade_uses_uv_hint(mocker, app_version, fake_settings, mock_pypi
153
result = runner.invoke(app, ["update"])
154
assert result.exit_code == 0
155
assert "available: 1.1.0 (current: 1.0.0)" in result.output
156
+ assert "You can run 'colab update --install' to upgrade in place." in result.output
157
assert "Run 'uv tool install -U google-colab-cli' to update." in result.output
158
159
+ idx_install = result.output.find(
160
+ "You can run 'colab update --install' to upgrade in place."
161
+ )
162
+ idx_uv = result.output.find("Run 'uv tool install -U google-colab-cli' to update.")
163
+ assert idx_install < idx_uv
164
+
165
+
166
+def test_pypi_upgrade_uses_pip_hint_non_linux(
167
+ mocker, app_version, fake_settings, mock_pypi
168
+):
169
+ app_version("1.0.0")
170
+ mock_pypi({"info": {"version": "1.1.0"}})
171
+ fake_settings()
172
+ mocker.patch("sys.executable", "/usr/bin/python")
173
+ mocker.patch("colab_cli.auto_update.platform.system", return_value="Darwin")
174
+
175
+ result = runner.invoke(app, ["update"])
176
+ assert result.exit_code == 0
177
+ assert "available: 1.1.0 (current: 1.0.0)" in result.output
178
+ assert (
179
+ "You can run 'colab update --install' to upgrade in place." not in result.output
180
+ )
181
+ assert "Run 'pip install --upgrade google-colab-cli' to update." in result.output
182
+
183
184
def test_explicit_update_omits_disable_hint(app_version, fake_settings, mock_pypi):
185
"""`colab update` is explicit user opt-in; the 'how to silence' line