Skip to content

feat: add --type flag to start for non-interactive emulator selection#381

Open
gtsiolis wants to merge 5 commits into
mainfrom
devx-985-add-type-flag-to-start-for-non-interactive-emulator-446a
Open

feat: add --type flag to start for non-interactive emulator selection#381
gtsiolis wants to merge 5 commits into
mainfrom
devx-985-add-type-flag-to-start-for-non-interactive-emulator-446a

Conversation

@gtsiolis

@gtsiolis gtsiolis commented Jul 10, 2026

Copy link
Copy Markdown
Member

Adds --type/-t (aws|snowflake|azure) to lstk start and the bare root command as the non-interactive answer to the first-run emulator picker. Because stop, status, logs, volume, and snapshot auto-load all resolve from the configured type, the flag records the selection in config rather than overriding it per-run — an ephemeral override would strand every follow-up command (none of them take --type), so persisting keeps config and reality in sync for CI scripts.

Behaviour:

  • No config yet: creates config with the selected type, reusing the picker's EnsureCreated/SetEmulatorType path.
  • Config matches: no-op.
  • Config differs: switches the type line in place via a surgical rewrite. The search is anchored to the active [[containers]] block (from its header to the next table header), so quotes, spacing, trailing comments, other keys, and any type key in another table (e.g. an [env.*] profile) are all left untouched. A note names the file.

On a switch the other block fields are kept, with guards: a custom image is a hard error (it pins a specific product that can't be reinterpreted under a new type — use --config for a separate profile); a non-latest tag and any volumes/volume are kept with a warning; port/env/snapshot are kept silently. A config with more than one [[containers]] block is rejected before any write, since only one block can start.

The domain logic lives in container.ApplyEmulatorType (parallel to container.SelectEmulator) and is applied at the top of startEmulator before snapshot/start-options are resolved, so it runs before the TUI.

Also in this PR:

  • A positional (lstk start azure) is rejected with a hint pointing at --type (previously it silently started AWS).
  • README CI examples for selecting the emulator non-interactively.

Dropped along the way (with why):

  • Positional emulator selection (lstk start azure as an accepted alias). lstk aws/lstk az are already proxy subcommands and lstk azure/lstk snowflake route to extension dispatch, so a positional could only work on start, never symmetrically on the bare root — it would teach a mental model the root contradicts. start now rejects a positional with a hint instead.

  • -c shorthand for --config. It was stripped from proxy args, which swallowed the -c flags wrapped tools own (CDK -c/--context, SAM -c/--cached) — e.g. lstk cdk synth -c env=prod failed with failed to read config file: open env=prod. --config stays long-form only; proxy commands forward -c to the wrapped tool.

  • Ephemeral per-run override (start Azure once without touching config). See the opening note: the follow-up commands are config-seeded, so a non-persistent flag would half-work. The flag persists instead.

Switch type Cannot switch type
Screenshot 2026-07-10 at 16 55 33 Screenshot 2026-07-10 at 16 56 15

Add --type/-t (aws|snowflake|azure) to `lstk start` and the bare root
command as the non-interactive answer to the first-run emulator picker.
It records the selection in config: creating the file on first run
(reusing the picker's EnsureCreated/SetEmulatorType path), no-op when the
configured type already matches, and switching the type line in place
when it differs (preserving comments/formatting, with a note naming the
file).

On switch, a custom `image` is a hard error (it pins a product that can't
be reinterpreted under a new type), a non-latest `tag` and any volume
mounts are kept with a warning, and `port`/`env`/`snapshot` are kept
silently. The type may also be given as a positional (`lstk start azure`)
and `start` now validates arg count. Also add a `-c` shorthand for
`--config` (stripped for proxy commands too) and a README CI example.

Generated with [Linear](https://linear.app/localstack/issue/DEVX-985/add-type-flag-to-start-for-non-interactive-emulator-selection#agent-session-09427df8)

Co-authored-by: linear-code[bot] <222613912+linear-code[bot]@users.noreply.github.com>
@gtsiolis gtsiolis self-assigned this Jul 10, 2026
@gtsiolis gtsiolis added semver: patch docs: needed Pull request requires documentation updates semver: minor and removed semver: patch labels Jul 10, 2026
SetEmulatorType replaced every `type = "..."` match in the file, so an
in-place `--type` switch could also rewrite commented-out example blocks,
a second [[containers]] block, or an unrelated `content_type` key. Anchor
the regex to the start of a line and splice only the first match's value,
so quotes, spacing, trailing comments, and other keys are all preserved.

Also reject a multi-block config before mutating it (the start path
rejects it anyway, so a rewrite would leave a half-changed config that
can't start), use the emulator's display name in the switch note for
casing consistency, and add regression tests plus coverage for the
bare-root `lstk --type` form.

Co-authored-by: Claude <noreply@anthropic.com>
@gtsiolis gtsiolis force-pushed the devx-985-add-type-flag-to-start-for-non-interactive-emulator-446a branch from fde3a84 to a3ea678 Compare July 10, 2026 10:06
gtsiolis added 3 commits July 10, 2026 13:28
The positional form (`lstk start azure`) implied a mental model the bare
root contradicts: `lstk aws`/`lstk az` are proxy subcommands that run the
wrapped CLI, and `lstk azure`/`lstk snowflake` route to extension
dispatch, so the positional could only ever work on `start`, never on the
bare root. Keep one self-documenting spelling — `--type`/`-t`, which works
identically on `start` and the bare root. A stray positional is now
rejected with a hint pointing at --type instead of silently starting AWS.
The -c shorthand added for --config was stripped from proxy args in
stripGlobalFlags, swallowing the -c flags that wrapped tools own (CDK's
-c/--context, SAM's -c/--cached). For example lstk cdk synth -c env=prod
failed with "failed to read config file: open env=prod". Drop the
shorthand: --config stays long-form only, and -c passes through to the
wrapped tool. --type/-t remains the emulator selector Maureen asked for.
Review follow-up. SetEmulatorType matched the first anchored type = "..."
line anywhere in the file, so a type key in an earlier table (e.g. an
[env.*] profile) would be rewritten instead of the container's — silently
failing the switch and corrupting an unrelated key. Scope the search to the
active [[containers]] block (from its header to the next table header), and
error clearly when the file has no such block.

Also guard the empty-config branch of ApplyEmulatorType (clear error instead
of a panic-prone containers[0] access) and fall back to a generic phrase when
the friendly config path is empty so the tag/volume/image messages still read
as sentences.
@gtsiolis gtsiolis marked this pull request as ready for review July 10, 2026 10:50
@gtsiolis gtsiolis requested a review from a team as a code owner July 10, 2026 10:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs: needed Pull request requires documentation updates semver: minor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant