1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
//! Handler for `trusty-search dashboard` — open the admin panel in a browser.
//!
//! Why: `dashboard` / `dash` / `ui` is a convenience entrypoint: the user
//! should never have to know which port the daemon chose or whether it is
//! running yet. Mirrors the trusty-analyze pattern from PR #685.
//!
//! What: calls `ensure_daemon_running_or_exit` which spawns the daemon in the
//! background if it is not yet running and polls `/health` until ready (60s
//! budget with a braille spinner). Then discovers the bound address via
//! `daemon_base_url()` (which reads `~/.trusty-search/http_addr` with TCP
//! fallbacks) and opens `http://<addr>/ui` in the default browser. On
//! browser-open failure (headless env) degrades gracefully by printing the
//! URL to stderr rather than returning an error.
//!
//! Test: `cargo run -- dashboard` with no daemon running spawns the daemon
//! and opens the browser; with the daemon already running, the probe returns
//! immediately and no spawn occurs; headless (no GUI) prints the URL.
use daemon_base_url;
use Result;
use Colorize;
/// Open the admin panel of the running daemon in the default browser.
///
/// Why: provides a one-command path from "is the daemon up?" to "show me the
/// UI" without the user having to memorise ports or run `trusty-search start`
/// first. Auto-starts the daemon when absent, matching the trusty-analyze
/// dashboard (#685) for a consistent UX across the suite.
/// What: ensures the daemon is running (spawning it in the background if
/// needed), resolves the bound address via `daemon_base_url()`, then opens
/// `http://<addr>/ui`. Browser-open failure degrades to a printed URL.
/// Test: `cargo test -p trusty-search -- dashboard` exercises the
/// already-healthy path. Manual: `cargo run -- dashboard` with no daemon
/// should print the "Starting…" spinner and then open the browser.
pub async
/// Construct the `/ui` URL from `base` and return it as a `String`.
///
/// Why: pure URL construction extracted as its own function so tests can
/// verify the correct path suffix is appended without triggering any I/O.
/// What: trims a trailing slash from `base` (guards against `http://h:p//ui`)
/// then appends `/ui`, returning the resulting `String`.
/// Test: `dashboard_url_is_constructed_correctly` and
/// `dashboard_url_has_no_double_slash` in this module cover the two
/// interesting inputs (plain base and base with trailing slash).
pub
/// Open `base`'s `/ui` path using the provided opener closure.
///
/// Why: extracted so tests can inject a fake opener that never calls the real
/// OS browser API — the historical `open_dashboard_url` called `open::that`
/// directly, which meant every `cargo test` on a macOS GUI session spawned a
/// dead browser tab to `http://127.0.0.1:19999/ui`.
/// What: constructs the URL via `dashboard_url`, prints it to stderr, then
/// calls `open_fn(&url)`. If `open_fn` returns `Err`, degrades gracefully by
/// printing a warning to stderr rather than propagating the error. Always
/// returns `Ok(())`.
/// Test: `open_dashboard_url_degrades_gracefully_on_headless` in this module
/// passes a closure that returns `Err` and asserts the result is `Ok(())`.
pub
/// Construct the `/ui` URL from `base` and open it in the default browser.
///
/// Why: thin public wrapper over `open_dashboard_url_with` using the real
/// `open::that` opener — keeps production behaviour identical while the inner
/// function remains testable via closure injection.
/// What: delegates to `open_dashboard_url_with(|u| open::that(u), base)`.
/// Browser-open failure degrades to a stderr warning; `Ok(())` is always
/// returned.
/// Test: not tested directly (the real `open::that` fires a browser). The
/// logic is fully covered by `open_dashboard_url_with` tests which inject a
/// fake opener.