Run the main watch loop until termination.
Termination conditions:
- The sentinel file .fpm-watch.stop exists, or
- The process receives an external termination (e.g., Ctrl+C).
Each iteration performs:
1. Sleep for poll seconds.
2. Scan for changes (fingerprints).
3. If changes were found, sleep for debounce seconds and rescan.
4. If fpm.toml changed, rebuild watch list.
5. Otherwise, run the computed fpm command (with target injection
for run/test), notify plugins, and accept fingerprints.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(watcher_t), | intent(inout) | :: | self |
subroutine watcher_run(self) class(watcher_t), intent(inout) :: self integer :: changed_count type(string_t), allocatable :: changed(:) character(len=:), allocatable :: cmd integer :: exitstat, j, idx real :: secs integer(int64) :: rate, t_last_rescan, t_now real :: dt if (self%cfg%w%once) return call system_clock(count_rate=rate) if (rate <= 0_int64) rate = 1000_int64 call system_clock(t_last_rescan) do if (exists(".fpm-watch.stop")) exit call sleep_seconds(self%cfg%w%poll) call scan_changes(self%files, self%fp_prev, self%fp_now, self%changed_idx, changed_count) if (changed_count > 0) then call sleep_seconds(self%cfg%w%debounce) call scan_changes(self%files, self%fp_prev, self%fp_now, self%changed_idx, changed_count) end if if (changed_count > 0) then if (any_manifest_changed(self%files, self%changed_idx, changed_count)) then call handle_manifest_change(self) cycle end if allocate(changed(changed_count)) do j = 1, changed_count idx = self%changed_idx(j) if (idx >= 1 .and. idx <= size(self%files)) then changed(j)%s = self%files(idx)%s else changed(j)%s = "" end if end do call self%fm%on_change_detected_all(changed) call report_changes(self%files, self%changed_idx, changed_count, self%cfg%w) cmd = build_run_command( & settings = self%cfg%settings, & full_cmdline = self%cfg%fpm_cmdline, & cmd_prefix = self%cfg%cmd_prefix, & cmd_rest = self%cfg%cmd_rest, & roots = self%roots, & file_mask = self%file_mask, & changed_idx = self%changed_idx, & changed_count = changed_count ) call self%fm%on_before_run_all(cmd) call run_command_and_report(cmd, self%cfg%w, exitstat, secs) call self%fm%on_after_run_all(exitstat, secs) call accept_changes(self%fp_prev, self%fp_now, self%changed_idx, changed_count) deallocate(changed) end if if (self%cfg%w%rescan > 0.0) then call system_clock(t_now) if (t_now < t_last_rescan) then t_last_rescan = t_now else dt = real(t_now - t_last_rescan) / real(rate) if (dt >= self%cfg%w%rescan) then call log_info(self%cfg%w, "rescan triggered -> rebuilding watch list") call rebuild_watch_list(self, print_header=.false.) call system_clock(t_last_rescan) end if end if end if end do end subroutine watcher_run