markdown · 7337 bytes Raw Blame History

fgof-devloop

Watch-driven rebuild, restart, and smoke-loop helpers for modern Fortran tools.

fgof-devloop is intended to be a small standalone library for the reusable parts of development loops: deciding when file changes should trigger work, tracking run cycles, modeling restart policy, and layering those decisions over fgof-watch, fgof-process, and fgof-jobs.

It is part of the FortranGoingOnForty lib-modules catalog, but it is intended to stand on its own as a normal fpm package.

Current v1 target:

  • stable dev-loop option and state types
  • deterministic cycle and restart decision helpers
  • watch-event shaping that can consume fgof-watch
  • process-runner integration that can supervise rebuild and run commands
  • long-running service/job restart planning over fgof-jobs
  • examples for command-line tools and local service smoke loops

Status

v0.1.0 is released.

Tracked today:

  • package layout, CI, and standalone repo setup
  • local sprint plan in ignored .docs/sprints/
  • stable option, trigger, cycle, decision, and state types
  • pure run-cycle helpers for start, finish, stop, and restart decisions
  • deterministic failure policy through stop_on_failure and max_failures
  • fgof-watch integration through shaped event summaries and trigger policy
  • loop-owned restart filters for directory events and minimum change counts
  • watch option projection for debounce polls, hidden-path ignores, and directory-event emission
  • fgof-process integration for one-shot build, run, and smoke command supervision
  • command results that retain full process_result output, exit, timeout, and error detail
  • fgof-jobs integration for long-running service ownership, wait observation, cleanup, and restart planning
  • pipeline-aware job observation that preserves terminal member state during group stop/continue events
  • released jobs are treated as unmanaged and will not receive restart/stop/start plans
  • tracked examples for watch-driven command cycles and service restart planning
  • CI coverage for both fpm test --verbose and fpm run --example --all
  • focused model, watch-bridge, process-supervision, job-supervision, and example coverage

Public API Shape

Primary modules:

  • fgof_devloop
  • fgof_devloop_types

Current public procedures:

  • clear_devloop_options
  • clear_devloop_trigger
  • clear_devloop_cycle
  • clear_devloop_decision
  • clear_devloop_watch_summary
  • clear_devloop_command_spec
  • clear_devloop_command_result
  • clear_devloop_supervision_result
  • clear_devloop_job_spec
  • clear_devloop_job_state
  • clear_devloop_job_plan
  • devloop_backend_name
  • clear_devloop_state
  • start_devloop
  • stop_devloop
  • should_start_on_open
  • devloop_start_trigger
  • devloop_change_trigger
  • devloop_manual_trigger
  • devloop_summarize_watch_events
  • devloop_watch_failure_summary
  • devloop_watch_options
  • devloop_watch_trigger
  • devloop_build_command
  • devloop_run_command
  • devloop_smoke_command
  • run_devloop_command
  • run_devloop_cycle
  • devloop_service_job
  • attach_devloop_job
  • attach_devloop_pipeline_members
  • observe_devloop_job
  • release_devloop_job
  • devloop_job_restart_plan
  • begin_devloop_cycle
  • finish_devloop_cycle

Current semantics:

  • devloop_options carries run-on-start, restart-on-change, directory restart, hidden-path ignore, debounce, stop-on-failure, and max-failure policy
  • devloop_trigger records why work should begin, such as start, file change, or manual request
  • devloop_watch_summary condenses fgof-watch event batches into file, directory, create, modify, remove, move, ignored, and failure counters
  • devloop_watch_options() projects dev-loop policy into fgof-watch options for debounce polls, hidden-path filtering, and directory event emission
  • devloop_watch_trigger() turns successful watch summaries into change triggers while suppressing watcher failures, disabled restart-on-change policy, empty batches, directory-only batches when disabled, and batches below min_restart_changes
  • devloop_change_trigger() suppresses nonpositive change counts so empty batches cannot start cycles through the lower-level trigger API
  • devloop_build_command(), devloop_run_command(), and devloop_smoke_command() wrap fgof-process commands with loop roles and optional process options
  • run_devloop_command() executes one command spec and preserves the raw process_result, including stdout, stderr, exit code, timeout state, and process error details
  • run_devloop_cycle() starts a cycle, executes enabled build/run/smoke specs in order, skips later specs after the first failure, and feeds the outcome into finish_devloop_cycle()
  • devloop_service_job() builds a long-running service/job spec backed by fgof-jobs
  • attach_devloop_job() records an already-launched pid/process group and ownership expectations
  • observe_devloop_job() applies fgof-jobs wait results while preserving member-level terminal state
  • devloop_job_restart_plan() models whether a watched change should stop, start, restart, release, or require terminal handoff for a long-running job; released jobs and release-on-handoff plans return no stop/start/restart action
  • begin_devloop_cycle() increments the cycle counter and starts work only when the loop is active, idle, and policy permits the trigger
  • finish_devloop_cycle() records success or failure and returns an explicit decision to idle, restart, or stop
  • negative max_failures values normalize to unlimited failures
  • negative debounce_polls values normalize to no debounce
  • Sprint 05 remains model-first: it plans and observes long-running job ownership, while actual spawning/signaling stays in the launcher layer

Dependency

fgof-devloop depends on fgof-watch v0.1.0 for watch-event types and watch option projection, fgof-process v0.1.1 for one-shot process execution, and fgof-jobs v0.1.0 for long-running job ownership and wait-state modeling:

[dependencies]
fgof-jobs = { git = "https://github.com/FortranGoingOnForty/fgof-jobs.git", tag = "v0.1.0" }
fgof-process = { git = "https://github.com/FortranGoingOnForty/fgof-process.git", tag = "v0.1.1" }
fgof-watch = { git = "https://github.com/FortranGoingOnForty/fgof-watch.git", tag = "v0.1.0" }

Build And Test

fpm test
fpm run --example --all

Examples

Tracked examples live in example/ and are intentionally deterministic:

  • watch_cycle_demo.f90 shapes a synthetic watch batch into a trigger, then runs build and smoke commands through fgof-process
  • service_restart_demo.f90 models restart and release behavior for a long-running service using an attached fgof-jobs handle

Supported Platforms

  • macOS
  • Linux

Boundaries

  • focused on reusable development-loop mechanics, not a full CLI app
  • should remain useful on its own even if future tools wrap it with UI policy
  • watch, process, and job integration should stay layered over stable state transitions
  • does not spawn long-running services or send signals directly; callers own launcher policy and use devloop_job_restart_plan() as the planning surface
  • uses tagged dependencies for the released process, watch, and jobs surfaces

License

MIT

View source
1 # fgof-devloop
2
3 Watch-driven rebuild, restart, and smoke-loop helpers for modern Fortran tools.
4
5 `fgof-devloop` is intended to be a small standalone library for the reusable
6 parts of development loops: deciding when file changes should trigger work,
7 tracking run cycles, modeling restart policy, and layering those decisions
8 over `fgof-watch`, `fgof-process`, and `fgof-jobs`.
9
10 It is part of the [FortranGoingOnForty lib-modules](https://github.com/FortranGoingOnForty/lib-modules)
11 catalog, but it is intended to stand on its own as a normal `fpm` package.
12
13 Current v1 target:
14
15 - stable dev-loop option and state types
16 - deterministic cycle and restart decision helpers
17 - watch-event shaping that can consume `fgof-watch`
18 - process-runner integration that can supervise rebuild and run commands
19 - long-running service/job restart planning over `fgof-jobs`
20 - examples for command-line tools and local service smoke loops
21
22 ## Status
23
24 `v0.1.0` is released.
25
26 Tracked today:
27
28 - package layout, CI, and standalone repo setup
29 - local sprint plan in ignored `.docs/sprints/`
30 - stable option, trigger, cycle, decision, and state types
31 - pure run-cycle helpers for start, finish, stop, and restart decisions
32 - deterministic failure policy through `stop_on_failure` and `max_failures`
33 - `fgof-watch` integration through shaped event summaries and trigger policy
34 - loop-owned restart filters for directory events and minimum change counts
35 - watch option projection for debounce polls, hidden-path ignores, and directory-event emission
36 - `fgof-process` integration for one-shot build, run, and smoke command supervision
37 - command results that retain full `process_result` output, exit, timeout, and error detail
38 - `fgof-jobs` integration for long-running service ownership, wait observation, cleanup, and restart planning
39 - pipeline-aware job observation that preserves terminal member state during group stop/continue events
40 - released jobs are treated as unmanaged and will not receive restart/stop/start plans
41 - tracked examples for watch-driven command cycles and service restart planning
42 - CI coverage for both `fpm test --verbose` and `fpm run --example --all`
43 - focused model, watch-bridge, process-supervision, job-supervision, and example coverage
44
45 ## Public API Shape
46
47 Primary modules:
48
49 - `fgof_devloop`
50 - `fgof_devloop_types`
51
52 Current public procedures:
53
54 - `clear_devloop_options`
55 - `clear_devloop_trigger`
56 - `clear_devloop_cycle`
57 - `clear_devloop_decision`
58 - `clear_devloop_watch_summary`
59 - `clear_devloop_command_spec`
60 - `clear_devloop_command_result`
61 - `clear_devloop_supervision_result`
62 - `clear_devloop_job_spec`
63 - `clear_devloop_job_state`
64 - `clear_devloop_job_plan`
65 - `devloop_backend_name`
66 - `clear_devloop_state`
67 - `start_devloop`
68 - `stop_devloop`
69 - `should_start_on_open`
70 - `devloop_start_trigger`
71 - `devloop_change_trigger`
72 - `devloop_manual_trigger`
73 - `devloop_summarize_watch_events`
74 - `devloop_watch_failure_summary`
75 - `devloop_watch_options`
76 - `devloop_watch_trigger`
77 - `devloop_build_command`
78 - `devloop_run_command`
79 - `devloop_smoke_command`
80 - `run_devloop_command`
81 - `run_devloop_cycle`
82 - `devloop_service_job`
83 - `attach_devloop_job`
84 - `attach_devloop_pipeline_members`
85 - `observe_devloop_job`
86 - `release_devloop_job`
87 - `devloop_job_restart_plan`
88 - `begin_devloop_cycle`
89 - `finish_devloop_cycle`
90
91 Current semantics:
92
93 - `devloop_options` carries run-on-start, restart-on-change, directory restart, hidden-path ignore, debounce, stop-on-failure, and max-failure policy
94 - `devloop_trigger` records why work should begin, such as start, file change, or manual request
95 - `devloop_watch_summary` condenses `fgof-watch` event batches into file, directory, create, modify, remove, move, ignored, and failure counters
96 - `devloop_watch_options()` projects dev-loop policy into `fgof-watch` options for debounce polls, hidden-path filtering, and directory event emission
97 - `devloop_watch_trigger()` turns successful watch summaries into change triggers while suppressing watcher failures, disabled restart-on-change policy, empty batches, directory-only batches when disabled, and batches below `min_restart_changes`
98 - `devloop_change_trigger()` suppresses nonpositive change counts so empty batches cannot start cycles through the lower-level trigger API
99 - `devloop_build_command()`, `devloop_run_command()`, and `devloop_smoke_command()` wrap `fgof-process` commands with loop roles and optional process options
100 - `run_devloop_command()` executes one command spec and preserves the raw `process_result`, including stdout, stderr, exit code, timeout state, and process error details
101 - `run_devloop_cycle()` starts a cycle, executes enabled build/run/smoke specs in order, skips later specs after the first failure, and feeds the outcome into `finish_devloop_cycle()`
102 - `devloop_service_job()` builds a long-running service/job spec backed by `fgof-jobs`
103 - `attach_devloop_job()` records an already-launched pid/process group and ownership expectations
104 - `observe_devloop_job()` applies `fgof-jobs` wait results while preserving member-level terminal state
105 - `devloop_job_restart_plan()` models whether a watched change should stop, start, restart, release, or require terminal handoff for a long-running job; released jobs and release-on-handoff plans return no stop/start/restart action
106 - `begin_devloop_cycle()` increments the cycle counter and starts work only when the loop is active, idle, and policy permits the trigger
107 - `finish_devloop_cycle()` records success or failure and returns an explicit decision to idle, restart, or stop
108 - negative `max_failures` values normalize to unlimited failures
109 - negative `debounce_polls` values normalize to no debounce
110 - Sprint 05 remains model-first: it plans and observes long-running job ownership, while actual spawning/signaling stays in the launcher layer
111
112 ## Dependency
113
114 `fgof-devloop` depends on `fgof-watch` `v0.1.0` for watch-event types and
115 watch option projection, `fgof-process` `v0.1.1` for one-shot process
116 execution, and `fgof-jobs` `v0.1.0` for long-running job ownership and
117 wait-state modeling:
118
119 ```toml
120 [dependencies]
121 fgof-jobs = { git = "https://github.com/FortranGoingOnForty/fgof-jobs.git", tag = "v0.1.0" }
122 fgof-process = { git = "https://github.com/FortranGoingOnForty/fgof-process.git", tag = "v0.1.1" }
123 fgof-watch = { git = "https://github.com/FortranGoingOnForty/fgof-watch.git", tag = "v0.1.0" }
124 ```
125
126 ## Build And Test
127
128 ```bash
129 fpm test
130 fpm run --example --all
131 ```
132
133 ## Examples
134
135 Tracked examples live in `example/` and are intentionally deterministic:
136
137 - `watch_cycle_demo.f90` shapes a synthetic watch batch into a trigger, then runs build and smoke commands through `fgof-process`
138 - `service_restart_demo.f90` models restart and release behavior for a long-running service using an attached `fgof-jobs` handle
139
140 ## Supported Platforms
141
142 - macOS
143 - Linux
144
145 ## Boundaries
146
147 - focused on reusable development-loop mechanics, not a full CLI app
148 - should remain useful on its own even if future tools wrap it with UI policy
149 - watch, process, and job integration should stay layered over stable state
150 transitions
151 - does not spawn long-running services or send signals directly; callers own
152 launcher policy and use `devloop_job_restart_plan()` as the planning surface
153 - uses tagged dependencies for the released process, watch, and jobs surfaces
154
155 ## License
156
157 MIT