From 610d6828fa8300efa3f8df3d3bf8e3c00e24c1dc Mon Sep 17 00:00:00 2001 From: historia Date: Mon, 24 Aug 2026 20:41:51 -0400 Subject: remove: partial feature to point at existing backend checkout --- app/backends/audiocpp.py | 101 ++++++------------------------------ app/backends/faster.py | 35 +++---------- app/backends/qwen.py | 19 ++----- app/tests/test_backends_audiocpp.py | 34 ------------ app/tests/test_tui.py | 71 ------------------------- app/ui/tui.py | 21 ++------ 6 files changed, 30 insertions(+), 251 deletions(-) (limited to 'app') diff --git a/app/backends/audiocpp.py b/app/backends/audiocpp.py index feeb22a..d4c79b0 100755 --- a/app/backends/audiocpp.py +++ b/app/backends/audiocpp.py @@ -94,7 +94,7 @@ AUDIOCPP_DIR_NAME = "audio.cpp" AUDIOCPP_GIT_URL = "https://github.com/0xShug0/audio.cpp" # Sentinel returned by tui.confirm (via its cancel_value) when the user -# presses Esc on an overwrite prompt to go back to the checkout browser +# presses Esc on an overwrite prompt to go back to the wav-directory browser # instead of aborting the wizard. _GO_BACK = object() @@ -161,38 +161,6 @@ def _resolve_audiocpp_root(directory: Path) -> Optional[Path]: return None -def _audiocpp_root_status(directory: Path) -> Tuple[str, str]: - """TUI status describing the directory listed in the checkout browser.""" - if _resolve_audiocpp_root(directory) is not None: - return ("model_specs/ found here", "ok") - return ("No model_specs/ directory here", "warn") - - -def _audiocpp_root_preview(directory: Path) -> Optional[Tuple[str, str]]: - """TUI status for a highlighted subdirectory in the checkout browser.""" - if (directory / "model_specs").is_dir(): - return ("contains model_specs/", "ok") - return None - - -def _checkout_auto_select(entry: Path) -> Optional[Path]: - """Auto-accept a highlighted checkout in the TUI browser. - - A subdirectory named ``audio.cpp`` that already contains a - ``model_specs`` directory is the audio.cpp checkout root, so it is - accepted immediately on Enter/Right (as if ``[ Use this directory ]`` - had been pressed) instead of being descended into. Anything else - returns None so the user keeps browsing. This is only consulted - while auto-accepting is still enabled; after the user presses Esc to - go back, the browser is restarted inside the previously accepted - checkout and this callback is no longer passed, so a wrong guess can - be corrected. - """ - if entry.name == "audio.cpp" and (entry / "model_specs").is_dir(): - return entry - return None - - # Backend display order, with short descriptions. The backend name is padded # so the descriptions' dashes line up in the menu. _BACKEND_DESCRIPTIONS = ( @@ -1058,54 +1026,6 @@ def _wizard(stdscr, args: argparse.Namespace, parser: argparse.ArgumentParser "unused_entries": s["unused_entries"], } - def screen_no_checkout(): - """First screen when no checkout exists: clone or browse. - - No ``back_value``: Esc aborts the whole wizard (nothing before it). - """ - choice = tui.menu( - stdscr, "No audio.cpp checkout found", - [(f"Clone into ./app/{AUDIOCPP_DIR_NAME} " - f"(from {AUDIOCPP_GIT_URL})", "clone"), - ("Browse for an existing checkout", "browse")], - help_lines=[ - "audio.cpp hosts the TTS model families " - "this generator uses.", - "Clone it into the project's app " - "directory, or point at an existing " - "checkout."]) - if choice == "clone": - target = APP_DIR / AUDIOCPP_DIR_NAME - with tui.suspend(stdscr): - rc = common.git_clone(AUDIOCPP_GIT_URL, target) - if rc != 0: - raise _TuiError( - f"git clone failed (exit {rc}). Clone " - f"audio.cpp manually: git clone " - f"{AUDIOCPP_GIT_URL} {target}") - resolve_checkout(target) - else: - return screen_browse_checkout - return _after_families() - - def screen_browse_checkout(): - """Browse for an existing checkout (Esc returns to the clone menu).""" - audiocpp_dir = tui.browse_directory( - stdscr, "Select your audio.cpp directory", - validate=lambda p: None if _resolve_audiocpp_root(p) - else "No model_specs/ directory here", - info=_audiocpp_root_status, - preview=_audiocpp_root_preview, - help_lines=["The root folder of your audio.cpp checkout;", - "it is the one that contains model_specs/"], - start=Path.cwd(), - auto_select=_checkout_auto_select, - back_value=_GO_BACK) - if audiocpp_dir is _GO_BACK: - return tui.Wizard.BACK - resolve_checkout(audiocpp_dir) - return _after_families() - def screen_families(): """Pick TTS model families and packages (the modify tree).""" tree_families = _build_tree_families(s["catalog"]) @@ -1385,15 +1305,24 @@ def _wizard(stdscr, args: argparse.Namespace, parser: argparse.ArgumentParser return _finalize() # First screen: resolve the checkout directly when it already exists - # (the modify flow), so the wizard starts on a real screen. + # (the modify flow), so the wizard starts on a real screen. When no + # checkout exists, clone it into ./app/audio.cpp without asking, then + # continue the same way. audiocpp_dir = args.audiocpp_dir if audiocpp_dir is None: audiocpp_dir = find_local_checkout() if audiocpp_dir is None: - first = screen_no_checkout - else: - resolve_checkout(audiocpp_dir) - first = _after_families() + target = APP_DIR / AUDIOCPP_DIR_NAME + with tui.suspend(stdscr): + rc = common.git_clone(AUDIOCPP_GIT_URL, target) + if rc != 0: + raise _TuiError( + f"git clone failed (exit {rc}). Clone " + f"audio.cpp manually: git clone " + f"{AUDIOCPP_GIT_URL} {target}") + audiocpp_dir = target + resolve_checkout(audiocpp_dir) + first = _after_families() return tui.Wizard().run(first) diff --git a/app/backends/faster.py b/app/backends/faster.py index e209ff2..36121ff 100755 --- a/app/backends/faster.py +++ b/app/backends/faster.py @@ -225,30 +225,11 @@ def _wizard(stdscr, args: argparse.Namespace) -> Optional[dict]: wav_start = next(iter(ref_dirs)) s["wav_start"] = wav_start - def screen_install(): - choice = tui.confirm(stdscr, "faster-qwen3-tts is not installed. " - "pip install it now?", default=True, - cancel_value=_GO_BACK) - if choice is _GO_BACK: - return tui.Wizard.BACK - s["do_install"] = choice - return _after_install() - - def _after_install(): - if not _is_cloned() and not args.skip_clone: - return screen_clone - s["do_clone"] = False - return _after_clone() - - def screen_clone(): - choice = tui.confirm( - stdscr, f"faster-qwen3-tts repo not cloned. Clone it into " - f"./app/{FASTER_DIR_NAME}?", default=True, - cancel_value=_GO_BACK) - if choice is _GO_BACK: - return tui.Wizard.BACK - s["do_clone"] = choice - return _after_clone() + # Install and clone happen without asking: when the package or repo is + # missing (and not skipped by flag), the wizard just does it and moves + # to the next screen. + s["do_install"] = (not _is_installed()) and not args.skip_install + s["do_clone"] = (not _is_cloned()) and not args.skip_clone def _after_clone(): if args.input_dir is None: @@ -361,11 +342,7 @@ def _wizard(stdscr, args: argparse.Namespace) -> Optional[dict]: "plan": s["plan"], } - if not _is_installed() and not args.skip_install: - first = screen_install - else: - first = _after_install() - return tui.Wizard().run(first) + return tui.Wizard().run(_after_clone()) def _try_language(value: str) -> bool: diff --git a/app/backends/qwen.py b/app/backends/qwen.py index 3416ebe..f1e7c79 100644 --- a/app/backends/qwen.py +++ b/app/backends/qwen.py @@ -71,15 +71,6 @@ def _wizard(stdscr, args: argparse.Namespace) -> Optional[dict]: _GO_BACK = object() s: dict = {} - def screen_install(): - choice = tui.confirm(stdscr, "qwen-tts is not installed. " - "pip install it now?", default=True, - cancel_value=_GO_BACK) - if choice is _GO_BACK: - return tui.Wizard.BACK - s["do_install"] = choice - return _after_install() - def _after_install(): if args.port_custom is None: return screen_custom_port @@ -145,11 +136,11 @@ def _wizard(stdscr, args: argparse.Namespace) -> Optional[dict]: "speaker": s["speaker"], } - if not _is_installed() and not args.skip_install: - first = screen_install - else: - first = _after_install() - return tui.Wizard().run(first) + # pip install happens without asking: when the package is missing (and + # not skipped by flag), the wizard just does it and moves to the next + # screen. + s["do_install"] = (not _is_installed()) and not args.skip_install + return tui.Wizard().run(_after_install()) def _execute(settings: dict) -> int: diff --git a/app/tests/test_backends_audiocpp.py b/app/tests/test_backends_audiocpp.py index dd19cd5..b724c0d 100644 --- a/app/tests/test_backends_audiocpp.py +++ b/app/tests/test_backends_audiocpp.py @@ -370,40 +370,6 @@ class NormalizeDirArgTests(unittest.TestCase): self.assertEqual(result, Path("/tmp/foo").resolve()) -class CheckoutAutoSelectTests(unittest.TestCase): - """TUI browser auto-accept callback for an audio.cpp checkout.""" - - def setUp(self): - self._td = tempfile.TemporaryDirectory() - self.root = Path(self._td.name) - - def tearDown(self): - self._td.cleanup() - - def test_accepts_audio_cpp_containing_model_specs(self): - checkout = self.root / "audio.cpp" - checkout.mkdir() - (checkout / "model_specs").mkdir() - self.assertEqual(make_server._checkout_auto_select(checkout), - checkout) - - def test_rejects_audio_cpp_without_model_specs(self): - checkout = self.root / "audio.cpp" - checkout.mkdir() - self.assertIsNone(make_server._checkout_auto_select(checkout)) - - def test_rejects_other_name_even_with_model_specs(self): - other = self.root / "not-audiocpp" - other.mkdir() - (other / "model_specs").mkdir() - self.assertIsNone(make_server._checkout_auto_select(other)) - - def test_rejects_plain_directory(self): - plain = self.root / "somewhere" - plain.mkdir() - self.assertIsNone(make_server._checkout_auto_select(plain)) - - class DefaultModelIdTests(unittest.TestCase): def test_preferred_ids_for_tested_families(self): self.assertEqual(make_server.default_model_id("qwen3_tts"), "qwen") diff --git a/app/tests/test_tui.py b/app/tests/test_tui.py index b206de7..d5cbb7e 100644 --- a/app/tests/test_tui.py +++ b/app/tests/test_tui.py @@ -687,13 +687,6 @@ class FormTests(TuiTestCase): self.assertEqual(result, {"first": "a", "second": "bx"}) -def _accept_audio_cpp(entry: Path): - """auto_select callback that accepts an 'audio.cpp' checkout root.""" - if entry.name == "audio.cpp" and (entry / "model_specs").is_dir(): - return entry - return None - - class BrowseDirectoryTests(TuiTestCase): def setUp(self): super().setUp() @@ -704,16 +697,6 @@ class BrowseDirectoryTests(TuiTestCase): (self.root / name).mkdir() (self.root / "noise.txt").write_text("x", encoding="utf-8") - def _checkout_tree(self): - """A temp dir containing an 'audio.cpp' checkout + a sibling dir.""" - tmp = tempfile.TemporaryDirectory() - self.addCleanup(tmp.cleanup) - root = Path(tmp.name) - (root / "audio.cpp").mkdir() - (root / "audio.cpp" / "model_specs").mkdir() - (root / "other").mkdir() - return root - def test_listing_rows_left_justified(self): screen = FakeScreen(keys=[10]) chosen = tui.browse_directory(screen, "Pick", start=self.root) @@ -735,60 +718,6 @@ class BrowseDirectoryTests(TuiTestCase): self.assertEqual(chosen, (self.root / "alpha").resolve()) self.assert_inside_border(screen) - def test_enter_auto_accepts_matching_subdir(self): - root = self._checkout_tree() - # sel 0 = [ Use this directory ], 1 = .., 2 = audio.cpp/ - keys = [FakeCurses.KEY_DOWN, FakeCurses.KEY_DOWN, 10] - screen = FakeScreen(keys=keys) - chosen = tui.browse_directory(screen, "Pick", start=root, - auto_select=_accept_audio_cpp) - self.assertEqual(chosen, (root / "audio.cpp").resolve()) - - def test_right_auto_accepts_matching_subdir(self): - root = self._checkout_tree() - keys = [FakeCurses.KEY_DOWN, FakeCurses.KEY_DOWN, - FakeCurses.KEY_RIGHT] - screen = FakeScreen(keys=keys) - chosen = tui.browse_directory(screen, "Pick", start=root, - auto_select=_accept_audio_cpp) - self.assertEqual(chosen, (root / "audio.cpp").resolve()) - - def test_use_this_directory_ignores_auto_select(self): - # Enter on '[ Use this directory ]' must accept the listed dir - # without ever consulting auto_select. - root = self._checkout_tree() - calls = [] - - def callback(entry): - calls.append(entry) - return entry # would auto-accept any subdir if consulted - - screen = FakeScreen(keys=[10]) - chosen = tui.browse_directory(screen, "Pick", start=root, - auto_select=callback) - self.assertEqual(chosen, root.resolve()) - self.assertEqual(calls, []) - - def test_auto_select_returning_none_descends_normally(self): - # A non-matching subdir (or a None reply) keeps browsing: Enter - # descends into it, then '[ Use this directory ]' accepts it. - root = self._checkout_tree() - calls = [] - - def callback(entry): - calls.append(entry) - return None - - # sel 0 = use, 1 = .., 2 = audio.cpp/, 3 = other/ - keys = [FakeCurses.KEY_DOWN, FakeCurses.KEY_DOWN, - FakeCurses.KEY_DOWN, 10, 10] - screen = FakeScreen(keys=keys) - chosen = tui.browse_directory(screen, "Pick", start=root, - auto_select=callback) - self.assertEqual(chosen, (root / "other").resolve()) - # auto_select was consulted only for the highlighted 'other/' row. - self.assertEqual([p.name for p in calls], ["other"]) - def test_esc_returns_back_value(self): marker = object() screen = FakeScreen(keys=[27]) diff --git a/app/ui/tui.py b/app/ui/tui.py index 0a119e9..f1abea1 100644 --- a/app/ui/tui.py +++ b/app/ui/tui.py @@ -1002,8 +1002,6 @@ def browse_directory(scr, title: str, preview: Optional[Callable[[Path], Optional[Tuple[str, str]]]] = None, help_lines: Optional[Sequence[str]] = None, - auto_select: Optional[Callable[ - [Path], Optional[Path]]] = None, back_value: object = None ) -> Path: """Pick a directory DOS-browser style. @@ -1023,15 +1021,9 @@ def browse_directory(scr, title: str, listed directory's path — kind is "ok" (green), "warn" (yellow), "err" (red), "info" (dim) or "input". PREVIEW(directory) returns one for the highlighted subdirectory, shown on the status line. - AUTO_SELECT receives a highlighted subdirectory when the user - opens it (Enter, Right or 'l') and may return a Path to accept - immediately — as if '[ Use this directory ]' had been pressed on - it — instead of descending; returning None keeps browsing. This - lets a subdirectory that already looks like the target (e.g. an - 'audio.cpp' checkout containing 'model_specs/') be picked in one - keystroke. Esc (or 'q') aborts the wizard unless BACK_VALUE is given - (not None), in which case either key returns it so the caller can - fall back a screen. + Esc (or 'q') aborts the wizard unless BACK_VALUE is given (not + None), in which case either key returns it so the caller can fall + back a screen. """ footer = ("Up/Down = move Enter = open/use Left = parent " "e = type path Esc = cancel") @@ -1119,12 +1111,7 @@ def browse_directory(scr, title: str, highlight = current current = current.parent else: - entry = entries[sel - offset] - if auto_select is not None: - picked = auto_select(entry) - if picked is not None: - return picked - current = entry + current = entries[sel - offset] sel = 0 elif key in (curses.KEY_LEFT, ord("h"), ord("u"), curses.KEY_BACKSPACE, 8, 127): -- cgit v1.2.3