[Feature] Guard platform-gated file pickers so #150 cannot regress #505

Closed
opened 2026-07-22 08:47:41 +00:00 by brenno · 1 comment
Owner

Problem / motivation

Issue #150 reported that buttons on the settings page did nothing in the web
demo. The cause was FilePicker.getDirectoryPath(), which has no web
implementation — the click silently did nothing. It was fixed in 4fa92fa8
(PR #148) by hiding those controls behind supportsLocalProjectFolders.

Nothing prevents that fix from being undone. No file under test/ references
supportsLocalProjectFolders or platform_features, and it cannot: the flag
comes in through a conditional import (lib/platform/platform_features.dart:3)
with no injection point, so under flutter test on the VM it is always true
and the web branch never runs. There is no --platform chrome target in the
Makefile. A newly added picker button without the platform check would pass the
full gate.

Proposed solution

A static rule in tool/check_web_hardening.dart: every FilePicker call in the
widget layer that reads a path must sit behind a platform gate. That file
already exists and already runs in make check-web; it currently knows nothing
about FilePicker. Verify the rule in both directions — zero on the repo, and
an alarm on a planted violation.

The six call sites that must stay gated:

  • lib/widgets/dialogs/parts/settings_dialog_storage.dart:73 and :436
  • lib/widgets/panels/slide_list_panel.dart:902
  • lib/widgets/shell/shell_actions.dart:33
  • lib/widgets/shell/shell_actions_connections.dart:107
  • lib/state/deck_provider.dart:282

Marp / file-format impact

None. This is a build-time check; it touches no deck data.

Alternatives considered

A widget test — rejected: it proves nothing here, because the broken branch is
unreachable under flutter test. Full browser test infrastructure — out of
proportion for one class of mistake.

**Problem / motivation** Issue #150 reported that buttons on the settings page did nothing in the web demo. The cause was `FilePicker.getDirectoryPath()`, which has no web implementation — the click silently did nothing. It was fixed in 4fa92fa8 (PR #148) by hiding those controls behind `supportsLocalProjectFolders`. Nothing prevents that fix from being undone. No file under `test/` references `supportsLocalProjectFolders` or `platform_features`, and it cannot: the flag comes in through a conditional import (`lib/platform/platform_features.dart:3`) with no injection point, so under `flutter test` on the VM it is always `true` and the web branch never runs. There is no `--platform chrome` target in the Makefile. A newly added picker button without the platform check would pass the full gate. **Proposed solution** A static rule in `tool/check_web_hardening.dart`: every `FilePicker` call in the widget layer that reads a `path` must sit behind a platform gate. That file already exists and already runs in `make check-web`; it currently knows nothing about `FilePicker`. Verify the rule in both directions — zero on the repo, and an alarm on a planted violation. The six call sites that must stay gated: - `lib/widgets/dialogs/parts/settings_dialog_storage.dart:73` and `:436` - `lib/widgets/panels/slide_list_panel.dart:902` - `lib/widgets/shell/shell_actions.dart:33` - `lib/widgets/shell/shell_actions_connections.dart:107` - `lib/state/deck_provider.dart:282` **Marp / file-format impact** None. This is a build-time check; it touches no deck data. **Alternatives considered** A widget test — rejected: it proves nothing here, because the broken branch is unreachable under `flutter test`. Full browser test infrastructure — out of proportion for one class of mistake.
Author
Owner

Correction to the proposed solution above: tool/check_web_hardening.dart is the wrong home. It reads build/web — the output of a web build — and so cannot reason about source at all.

The rule belongs in tool/check_conventions.dart, which is the source-level convention gate: it already carries the ratchets, the layer rules and audienceBoundary, and it is wired into make check rather than the slower make check-web.

Also flipping the order with #506: the new rule should land on a zero baseline, which means the logo picker must be gated first. The "can it go red" requirement is met by a planted-violation test inside the check's own test, which is stronger than a one-off manual red run.

Correction to the proposed solution above: `tool/check_web_hardening.dart` is the wrong home. It reads `build/web` — the *output* of a web build — and so cannot reason about source at all. The rule belongs in `tool/check_conventions.dart`, which is the source-level convention gate: it already carries the ratchets, the layer rules and `audienceBoundary`, and it is wired into `make check` rather than the slower `make check-web`. Also flipping the order with #506: the new rule should land on a zero baseline, which means the logo picker must be gated first. The "can it go red" requirement is met by a planted-violation test inside the check's own test, which is stronger than a one-off manual red run.
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
LibreKAT/Ocideck#505
No description provided.