diff --git a/scripts/build.py b/scripts/build.py index 189b6fd..4b92866 100755 --- a/scripts/build.py +++ b/scripts/build.py @@ -733,54 +733,96 @@ def _print_platform_log(r: PlatformResult, verbose: bool = False) -> None: # --------------------------------------------------------------------------- -def prompt_platforms(platforms: list[Platform], alias_map: dict[str, Platform]) -> list[Platform]: - choices = [ - questionary.Choice("All platforms", value="all", checked=True), - *[questionary.Choice(p.label, value=p.alias) for p in platforms], - ] - selected = questionary.checkbox("Select platforms:", choices=choices, style=PROMPT_STYLE).ask() - if selected is None: - sys.exit(0) - if "all" in selected or not selected: - return list(platforms) - return [alias_map[alias] for alias in selected] +def _native_platforms(platforms: list[Platform]) -> list[Platform]: + return [p for p in platforms if p.native] -def prompt_targets() -> BuildConfig: - choices = [ - questionary.Choice("cagire (CLI)", value="cli", checked=True), - questionary.Choice("cagire-desktop", value="desktop", checked=True), - questionary.Choice("cagire-plugins (CLAP/VST3)", value="plugins", checked=True), - ] - selected = questionary.checkbox("Select targets:", choices=choices, style=PROMPT_STYLE).ask() - if selected is None: +def _platforms_by_os(platforms: list[Platform], os_name: str) -> list[Platform]: + return [p for p in platforms if p.os == os_name] + + +def _build_presets(platforms: list[Platform]) -> list[tuple[str, list[Platform], BuildConfig]]: + """Build a list of (label, platforms, config) presets.""" + presets: list[tuple[str, list[Platform], BuildConfig]] = [] + + native = _native_platforms(platforms) + if native: + label = ", ".join(p.label for p in native) + presets.append((f"This machine ({label})", native, BuildConfig())) + + macos = _platforms_by_os(platforms, "macos") + if len(macos) > 1: + presets.append(("macOS all (arm64 + x86_64)", macos, BuildConfig())) + + presets.append(("Full release (all platforms, all targets)", list(platforms), BuildConfig())) + presets.append(("CLI only (all platforms, no desktop/plugins)", list(platforms), BuildConfig(desktop=False, plugins=False))) + return presets + + +def _ask_or_exit(prompt) -> any: + result = prompt.ask() + if result is None: sys.exit(0) - if not selected: - return BuildConfig() - return BuildConfig( - cli="cli" in selected, - desktop="desktop" in selected, - plugins="plugins" in selected, + return result + + +def prompt_interactive( + all_platforms: list[Platform], alias_map: dict[str, Platform], +) -> tuple[list[Platform], BuildConfig]: + presets = _build_presets(all_platforms) + + choices = [ + *[questionary.Choice(label, value=i) for i, (label, _, _) in enumerate(presets)], + questionary.Separator(), + questionary.Choice("Custom...", value="custom"), + ] + + pick = _ask_or_exit(questionary.select( + "Build profile:", choices=choices, style=PROMPT_STYLE, + )) + + if pick != "custom": + _, platforms, config = presets[pick] + _print_summary(platforms, config) + return platforms, config + + # Custom: platform checkboxes + plat_choices = [questionary.Choice(p.label, value=p.alias, checked=p.native) for p in all_platforms] + selected_aliases = _ask_or_exit(questionary.checkbox( + "Platforms:", choices=plat_choices, style=PROMPT_STYLE, + )) + if not selected_aliases: + selected_aliases = [p.alias for p in all_platforms] + platforms = [alias_map[a] for a in selected_aliases] + + # Custom: target checkboxes + target_choices = [ + questionary.Choice("CLI", value="cli", checked=True), + questionary.Choice("Desktop", value="desktop", checked=True), + questionary.Choice("Plugins (CLAP/VST3)", value="plugins", checked=True), + ] + selected_targets = _ask_or_exit(questionary.checkbox( + "Targets:", choices=target_choices, style=PROMPT_STYLE, + )) + if not selected_targets: + selected_targets = ["cli", "desktop", "plugins"] + config = BuildConfig( + cli="cli" in selected_targets, + desktop="desktop" in selected_targets, + plugins="plugins" in selected_targets, ) + _print_summary(platforms, config) + return platforms, config -def confirm_summary(platforms: list[Platform], config: BuildConfig) -> None: - console.print("[bold]Platforms:[/]") - for p in platforms: - console.print(f" [cyan]{p.label}[/]") - console.print("[bold]Targets:[/]") - if config.cli: - console.print(" cagire") - if config.desktop: - console.print(" cagire-desktop") - if config.plugins: - console.print(" cagire-plugins") + +def _print_summary(platforms: list[Platform], config: BuildConfig) -> None: + targets = [t for t, on in [("cli", config.cli), ("desktop", config.desktop), ("plugins", config.plugins)] if on] + plat_str = ", ".join(p.alias for p in platforms) + console.print(f" [dim]platforms:[/] {plat_str}") + console.print(f" [dim]targets:[/] {', '.join(targets)}") console.print() - if not questionary.confirm("Proceed?", default=True, style=PROMPT_STYLE).ask(): - console.print("[dim]Aborted.[/]") - sys.exit(0) - def print_results(results: list[PlatformResult], wall_time: float) -> None: table = Table(title="Results", title_style="bold") @@ -907,7 +949,6 @@ def main() -> None: parser.add_argument("--platforms", help="Comma-separated: macos-arm64,macos-x86_64,linux-x86_64,linux-aarch64,windows-x86_64") parser.add_argument("--targets", help="Comma-separated: cli,desktop,plugins") parser.add_argument("--all", action="store_true", help="Build all platforms and targets") - parser.add_argument("--yes", action="store_true", help="Skip confirmation prompt") parser.add_argument("--verbose", "-v", action="store_true", help="Show build logs for all platforms (not just failures)") parser.add_argument("--force", action="store_true", help="Allow building from a dirty git tree") parser.add_argument("--no-checksums", action="store_true", help="Skip SHA256 checksum generation") @@ -934,11 +975,7 @@ def main() -> None: platforms = resolve_cli_platforms(args.platforms, alias_map) if args.platforms else list(all_platforms) config = resolve_cli_targets(args.targets) if args.targets else BuildConfig() else: - platforms = prompt_platforms(all_platforms, alias_map) - config = prompt_targets() - - if not args.yes and not args.all and not (args.platforms or args.targets): - confirm_summary(platforms, config) + platforms, config = prompt_interactive(all_platforms, alias_map) check_prerequisites(platforms, config)