Skip to content

Commit edef0bf

Browse files
committed
Show RPC connection status in forwarded builds
Add a composable status-line section for RPC-connected clients and cover it with focused console and cram tests. Signed-off-by: Rudi Grinberg <me@rgrinberg.com>
1 parent 5c705ee commit edef0bf

5 files changed

Lines changed: 95 additions & 8 deletions

File tree

bin/rpc/rpc_common.ml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,11 +122,21 @@ let should_warn ~warn_forwarding builder =
122122
&& not (Common.Builder.equal builder Common.Builder.default)
123123
;;
124124

125+
let with_rpc_connected_status_line f =
126+
let section =
127+
Console.Status_line.add_section
128+
(Live (fun () -> Pp.verbatim "Connected to RPC server"))
129+
in
130+
Fiber.finalize f ~finally:(fun () ->
131+
Console.Status_line.remove_section section;
132+
Fiber.return ())
133+
;;
134+
125135
let send_request ~f connection name =
126136
Dune_rpc_impl.Client.client
127137
connection
128138
(Dune_rpc.Initialize.Request.create ~id:(Dune_rpc.Id.make (Sexp.Atom name)))
129-
~f
139+
~f:(fun client -> with_rpc_connected_status_line (fun () -> f client))
130140
;;
131141

132142
let fire_request

otherlibs/stdune/src/console.ml

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,32 @@ module Status_line = struct
143143

144144
let toplevel = Id.gen ()
145145
let stack = ref []
146+
let sections = ref []
147+
148+
let pp_if_not_nop t =
149+
let pp =
150+
match t with
151+
| Live f -> f ()
152+
| Constant x -> x
153+
in
154+
match Pp.to_ast pp with
155+
| Nop -> []
156+
| _ -> [ pp ]
157+
;;
146158

147159
let refresh () =
148-
match !stack with
149-
| [] -> set_status_line None
150-
| (_id, t) :: _ ->
151-
let pp =
152-
match t with
153-
| Live f -> f ()
154-
| Constant x -> x
160+
let pps =
161+
let section_pps =
162+
List.rev !sections |> List.concat_map ~f:(fun (_id, t) -> pp_if_not_nop t)
155163
in
164+
match !stack with
165+
| [] -> section_pps
166+
| (_id, t) :: _ -> pp_if_not_nop t @ section_pps
167+
in
168+
match pps with
169+
| [] -> set_status_line None
170+
| _ :: _ ->
171+
let pp = Pp.concat pps ~sep:(Pp.verbatim " | ") in
156172
(* Always put the status line inside a horizontal box to force the
157173
[Format] module to prefer a single line. In particular, it seems that
158174
[Format.pp_print_text] split the line before the last word, unless it
@@ -194,6 +210,20 @@ module Status_line = struct
194210
let id = add_overlay t in
195211
Exn.protect ~f ~finally:(fun () -> remove_overlay id)
196212
;;
213+
214+
type section = Id.t
215+
216+
let add_section t =
217+
let id = Id.gen () in
218+
sections := (id, t) :: !sections;
219+
refresh ();
220+
id
221+
;;
222+
223+
let remove_section id =
224+
sections := List.filter !sections ~f:(fun (id', _) -> not (Id.equal id id'));
225+
refresh ()
226+
;;
197227
end
198228

199229
let () = User_warning.set_reporter print_user_message

otherlibs/stdune/src/console.mli

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,5 +130,15 @@ module Status_line : sig
130130
]} *)
131131
val with_overlay : t -> f:(unit -> 'a) -> 'a
132132

133+
type section
134+
135+
(** Add a section to the current status line. Sections are rendered after the
136+
current status line, separated by [" | "], and stay active across [set]
137+
and [clear] until removed. *)
138+
val add_section : t -> section
139+
140+
(** Remove a section if it is still active. Do nothing otherwise. *)
141+
val remove_section : section -> unit
142+
133143
val refresh : unit -> unit
134144
end
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
Forwarded builds display a rich status line once connected over RPC.
2+
3+
$ echo "(lang dune 3.23)" > dune-project
4+
5+
$ cat > dune <<EOF
6+
> (rule
7+
> (target x)
8+
> (action (write-file %{target} ok)))
9+
> EOF
10+
11+
$ start_dune
12+
$ INSIDE_EMACS=1 DUNE_CONFIG__THREADED_CONSOLE=disabled \
13+
> with_timeout dune build --display progress x > output 2>&1
14+
$ tr '\r' '\n' < output | grep -m 1 "Connected to RPC server"
15+
Connected to RPC server
16+
17+
$ stop_dune_quiet

test/expect-tests/dune_console/dune_console_tests.ml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,17 @@ let test_status_line_overwrite (module Console : New_console) =
6565
Status_line.clear ()
6666
;;
6767

68+
let test_status_line_section (module Console : New_console) =
69+
let open Console in
70+
Status_line.set (Status_line.Live (fun () -> Pp.text "Done: 50%"));
71+
let section =
72+
Status_line.add_section
73+
(Status_line.Live (fun () -> Pp.text "Connected to RPC server"))
74+
in
75+
Status_line.remove_section section;
76+
Status_line.clear ()
77+
;;
78+
6879
(* Dumb backend *)
6980

7081
let%expect_test "basic usage" =
@@ -193,3 +204,12 @@ let%expect_test "Status line overwriting." =
193204
Here is a status line\r \rHere is another status line\r \r
194205
|}]
195206
;;
207+
208+
let%expect_test "Status line sections." =
209+
let module Console = New () in
210+
Console.Backend.set Console.Backend.progress;
211+
test_status_line_section (module Console);
212+
escape [%expect.output];
213+
[%expect
214+
{| Done: 50%\r \rDone: 50% | Connected to RPC server\r \rDone: 50%\r \r |}]
215+
;;

0 commit comments

Comments
 (0)