Skip to content

Make InstallerTypes the single source of truth for installer type handling #1285

Description

@lrandersson

Checklist

  • I added a descriptive title
  • I searched open requests and couldn't find a duplicate

What is the idea?

Make InstallerTypes (already defined as a StrEnum in constructor/_schema.py, covering ALL, EXE, MSI, PKG, SH, DOCKER) the single source of truth for installer type handling throughout the codebase, instead of raw string literals.

Today the enum is only used as a type annotation on the installer_type field. Everywhere else — main.py's os_allowed/all_allowed, and comparisons in main.py, osxpkg.py, imaging.py, briefcase.py — installer types are handled as plain strings ("sh", "pkg", "exe", "msi", "docker", "all"), duplicated independently of the schema enum.

Why is this needed?

  1. main.py's allowed-type tables are hardcoded string tuples, fully disconnected from InstallerTypes. Adding a new installer type means updating both places by hand, with nothing enforcing they stay in sync.
  2. String comparisons against installer type literals are scattered across several files, are typo-prone, and aren't statically checked.
  3. Error messages listing valid installer type values are also hand-maintained strings that can drift from the actual supported set.
  4. The --installer-type CLI flag has no choices= constraint, so invalid values are only caught later through manual validation, giving a less helpful CLI error than argparse could provide for free.

What should happen?

  1. InstallerTypes becomes the canonical definition of valid installer types, including DOCKER and ALL (already present as members — docker does not need its own enum).
  2. Allowed-type tables in main.py are derived from InstallerTypes rather than duplicating string tuples.
  3. Comparison sites across main.py, osxpkg.py, imaging.py, briefcase.py switch to comparing against InstallerTypes members.
  4. Optionally, the --installer-type CLI flag gains choices= derived from InstallerTypes for earlier validation and clearer errors.

Since InstallerTypes is a StrEnum, its members compare equal to and serialize as plain strings, so construct.yaml parsing, info.json metadata, and existing string-based test parametrization should continue to work without changes.

Additional Context

Open questions for discussion:

  • Test literals: Should tests/test_examples.py / tests/test_main.py also be migrated to use InstallerTypes, or is leaving them as raw strings acceptable given StrEnum compatibility?
  • CLI behavior change: Adding choices= to --installer-type changes the argparse error message for invalid values — minor user-facing change worth flagging in the PR.
  • Docs generation: CONSTRUCT.md / docs/source/construct-yaml.md are generated from hand-written docstring prose on the installer_type field, not from iterating InstallerTypes members. Keeping that docstring in sync with the enum is a separate concern and not required for this change.

There are likely more but just for the sake of bookkeeping.

Metadata

Metadata

Assignees

No one assigned

    Labels

    type::featurerequest for a new feature or capability

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions