Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

User-configured watch exclusions #7216

Merged
merged 11 commits into from
Mar 23, 2023
Merged
2 changes: 2 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ Unreleased
- Speed up rule generation for libraries and executables with many modules
(#7187, @jchavarri)

- Add `--watch-exclusions` to Dune build options (#7216, @jonahbeckford)

- Do not re-render UI on every frame if the UI doesn't change (#7186, fix
#7184, @rgrinberg)

Expand Down
1 change: 1 addition & 0 deletions bench/bench.ml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ let () =
; stats = None
; insignificant_changes = `React
; signal_watcher = `No
; watch_exclusions = []
}
in
let clean, zero =
Expand Down
1 change: 1 addition & 0 deletions bench/micro/dune_bench/scheduler_bench.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ let config =
; stats = None
; insignificant_changes = `React
; signal_watcher = `No
; watch_exclusions = []
}

let setup =
Expand Down
40 changes: 40 additions & 0 deletions bin/common.ml
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,7 @@ module Builder = struct
; separate_error_messages : bool
; require_dune_project_file : bool
; insignificant_changes : [ `React | `Ignore ]
; watch_exclusions : string list
; build_dir : string
; store_digest_preimage : bool
; root : string option
Expand All @@ -538,6 +539,20 @@ module Builder = struct

let set_root t root = { t with root = Some root }

(** Cmdliner documentation markup language
(https://erratique.ch/software/cmdliner/doc/tool_man.html#doclang)
requires that dollar signs (ex. $(tname)) and backslashes are escaped. *)
let docmarkup_escape s =
let b = Buffer.create (2 * String.length s) in
for i = 0 to String.length s - 1 do
match s.[i] with
| ('$' | '\\') as c ->
Buffer.add_char b '\\';
Buffer.add_char b c
| c -> Buffer.add_char b c
done;
Buffer.contents b

let term =
let docs = copts_sect in
let+ config_from_command_line = shared_with_config_file
Expand Down Expand Up @@ -765,6 +780,28 @@ module Builder = struct
])
Automatic
& info [ "file-watcher" ] ~doc)
and+ watch_exclusions =
let std_exclusions = Dune_config.standard_watch_exclusions in
let doc =
let escaped_std_exclusions =
List.map ~f:docmarkup_escape std_exclusions
in
"Adds a POSIX regular expression that will exclude matching \
directories from $(b,`dune build --watch`). The option $(opt) can be \
repeated to add multiple exclusions. Semicolons can be also used as a \
separator. If no exclusions are provided, then a standard set of \
exclusions is used; however, if $(i,one or more) $(opt) are used, \
$(b,none) of the standard exclusions are used. The standard \
exclusions are: "
^ String.concat ~sep:" " escaped_std_exclusions
in
let arg =
Arg.(
value
& opt_all (list ~sep:';' string) [ std_exclusions ]
& info [ "watch-exclusions" ] ~docs ~docv:"REGEX" ~doc)
in
Term.(const List.flatten $ arg)
and+ wait_for_filesystem_clock =
Arg.(
value & flag
Expand Down Expand Up @@ -853,6 +890,7 @@ module Builder = struct
; require_dune_project_file
; insignificant_changes =
(if react_to_insignificant_changes then `React else `Ignore)
; watch_exclusions
; build_dir = Option.value ~default:default_build_dir build_dir
; store_digest_preimage
; root
Expand Down Expand Up @@ -905,6 +943,8 @@ let signal_watcher t =
(* if we aren't building anything, then we don't mind interrupting dune immediately *)
`No

let watch_exclusions t = t.builder.watch_exclusions

let stats t = t.stats

let insignificant_changes t = t.builder.insignificant_changes
Expand Down
2 changes: 2 additions & 0 deletions bin/common.mli
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ val forbid_builds : t -> t

val signal_watcher : t -> [ `Yes | `No ]

val watch_exclusions : t -> string list

val stats : t -> Dune_stats.t option

val print_metrics : t -> bool
Expand Down
6 changes: 4 additions & 2 deletions bin/import.ml
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,9 @@ module Scheduler = struct
let config =
let insignificant_changes = Common.insignificant_changes common in
let signal_watcher = Common.signal_watcher common in
let watch_exclusions = Common.watch_exclusions common in
Dune_config.for_scheduler dune_config stats ~insignificant_changes
~signal_watcher
~signal_watcher ~watch_exclusions
in
let f =
match Common.rpc common with
Expand All @@ -174,8 +175,9 @@ module Scheduler = struct
let config =
let signal_watcher = Common.signal_watcher common in
let insignificant_changes = Common.insignificant_changes common in
let watch_exclusions = Common.watch_exclusions common in
Dune_config.for_scheduler dune_config stats ~insignificant_changes
~signal_watcher
~signal_watcher ~watch_exclusions
in
let file_watcher = Common.file_watcher common in
let run () =
Expand Down
4 changes: 2 additions & 2 deletions bin/subst.ml
Original file line number Diff line number Diff line change
Expand Up @@ -437,8 +437,8 @@ let term =
Log.init_disabled ();
Dune_engine.Scheduler.Run.go
~on_event:(fun _ _ -> ())
(Dune_config.for_scheduler config None ~insignificant_changes:`React
~signal_watcher:`No)
(Dune_config.for_scheduler config ~watch_exclusions:[] None
~insignificant_changes:`React ~signal_watcher:`No)
subst

let command = Cmd.v info term
21 changes: 20 additions & 1 deletion src/dune_config_file/dune_config_file.ml
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,23 @@ module Dune_config = struct
let field f = f
end)

let standard_watch_exclusions =
[ {|^_opam|}
; {|/_opam|}
; {|^_esy|}
; {|/_esy|}
; {|^\.#.*|} (* Such files can be created by Emacs and also Dune itself. *)
; {|/\.#.*|}
; {|~$|}
; {|^#[^#]*#$|}
; {|/#[^#]*#$|}
; {|^4913$|} (* https://github.com/neovim/neovim/issues/3460 *)
; {|/4913$|}
; {|/.git|}
; {|/.hg|}
; {|:/windows|}
]

let hash = Poly.hash

let equal a b = Poly.equal a b
Expand Down Expand Up @@ -460,7 +477,8 @@ module Dune_config = struct
in
loop commands)

let for_scheduler (t : t) stats ~insignificant_changes ~signal_watcher =
let for_scheduler (t : t) ~watch_exclusions stats ~insignificant_changes
~signal_watcher =
let concurrency =
match t.concurrency with
| Fixed i -> i
Expand All @@ -477,5 +495,6 @@ module Dune_config = struct
; stats
; insignificant_changes
; signal_watcher
; watch_exclusions
}
end
8 changes: 8 additions & 0 deletions src/dune_config_file/dune_config_file.mli
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ module Dune_config : sig
val to_dyn : t -> Dyn.t
end

(** A standard list of watch exclusions *)
val standard_watch_exclusions : string list

val decode : Partial.t Dune_lang.Decoder.t

(** Decode the same fields as the one accepted in the configuration file, but
Expand Down Expand Up @@ -122,8 +125,13 @@ module Dune_config : sig

val equal : t -> t -> bool

(** [for_scheduler config ?watch_exclusions stats_opt ~insignificant_changes
~signal_watcher]
creates a configuration for a scheduler from the user-visible Dune
[config]. *)
val for_scheduler :
t
-> watch_exclusions:string list
-> Dune_stats.t option
-> insignificant_changes:[ `React | `Ignore ]
-> signal_watcher:[ `Yes | `No ]
Expand Down
3 changes: 2 additions & 1 deletion src/dune_engine/scheduler.ml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module Config = struct
; stats : Dune_stats.t option
; insignificant_changes : [ `Ignore | `React ]
; signal_watcher : [ `Yes | `No ]
; watch_exclusions : string list
}
end

Expand Down Expand Up @@ -1234,7 +1235,7 @@ module Run = struct
; thread_safe_send_emit_events_job =
(fun job -> Event_queue.send_file_watcher_task events job)
}
())
~watch_exclusions:config.watch_exclusions ())
in
let t = prepare ~file_watcher in
let initial_invalidation = Fs_memo.init ~dune_file_watcher:file_watcher in
Expand Down
1 change: 1 addition & 0 deletions src/dune_engine/scheduler.mli
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Config : sig
; stats : Dune_stats.t option
; insignificant_changes : [ `Ignore | `React ]
; signal_watcher : [ `Yes | `No ]
; watch_exclusions : string list
}
end

Expand Down
Loading