markdown · 5094 bytes Raw Blame History

fgof-state

Persistent app and workspace state helpers for modern Fortran.

fgof-state is intended to be a small, standalone library for durable local state, atomic save flows, and version-aware app data that CLI tools and interactive apps keep hand-rolling.

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 state option, root, and document types
  • predictable state-root resolution from explicit paths or XDG defaults
  • atomic save or replace semantics for app and workspace state
  • simple version-aware load or save flows with room for migrations later

Future scope:

  • richer schema migration helpers
  • backup or recovery helpers for state upgrades
  • higher-level workspace and session persistence flows

Status

Sprint 04 is in place.

Tracked today:

  • explicit state-root resolution from root_dir, XDG_STATE_HOME, or HOME
  • namespace and scope-aware root layout
  • document-path helpers and document resolution
  • text-focused state save, load, and remove helpers
  • fgof-temp-backed atomic replace semantics for saves
  • side-effect-free reads and removes when state roots are missing
  • version-aware state envelopes with explicit mismatch handling
  • explicit version_checked / version_matched result semantics for version-aware loads
  • malformed or unsupported state payloads rejected as version errors
  • unreadable state files reported as io failures
  • invalid version arguments rejected before filesystem writes
  • tracked round-trip and version-mismatch examples
  • POSIX root creation and existence checks
  • focused scaffold coverage in fpm test
  • CI on macOS and Ubuntu, including direct example execution

Why Use It

  • app and workspace state shows up everywhere once tools grow past trivial size
  • atomic persistence is easy to get subtly wrong
  • a focused state layer builds naturally on the released temp and cache modules

Public API Shape

Primary modules:

  • fgof_state
  • fgof_state_types

Public types:

  • state_options
  • state_root
  • state_document
  • state_text_result

Public constants:

  • FGOF_STATE_OK
  • FGOF_STATE_ERR_INVALID_OPTIONS
  • FGOF_STATE_ERR_NOT_FOUND
  • FGOF_STATE_ERR_IO
  • FGOF_STATE_ERR_VERSION
  • FGOF_STATE_ERR_INTERNAL

Current public procedures:

  • clear_state_options
  • clear_state_root
  • clear_state_document
  • clear_state_text_result
  • ensure_state_root
  • save_state_text
  • load_state_text
  • remove_state_document
  • state_relative_path_for_name
  • state_path_for_name
  • resolve_state_document
  • state_backend_name
  • state_error_name

Current semantics:

  • ensure_state_root() resolves from explicit root_dir, or from XDG_STATE_HOME / HOME when root_dir is absent
  • explicit namespace and scope values extend the resolved root path as validated path segments
  • create_root=.true. creates state directories on demand; create_root=.false. requires the root to already exist
  • state_relative_path_for_name() and state_path_for_name() expose the stable document path shape for valid document names
  • resolve_state_document() returns the resolved root path, relative path, full path, and current presence state for a state document
  • save_state_text() writes exact Fortran character payloads with same-directory atomic replacement through fgof-temp
  • load_state_text() reads stored text back without creating missing roots as a side effect
  • remove_state_document() removes stored state files without creating missing roots as a side effect
  • save_state_text() stores a small internal format header plus a positive document version; the default version is 1
  • load_state_text() surfaces the stored version on state_text_result%document%version
  • state_text_result%version_checked tells callers whether expected_version= was actually applied for that load
  • load_state_text(..., expected_version=...) reports version errors explicitly when the stored document version does not match the caller expectation
  • state_text_result%version_matched is only meaningful when state_text_result%version_checked is .true.
  • unsupported or malformed state payloads also report version errors instead of pretending to be valid text
  • unreadable state files report io errors during load
  • missing documents report not-found for load or remove flows
  • document names, namespaces, and scopes must not be empty, contain /, or be . / ..

Build And Test

fpm test

That is the baseline verification command locally and in CI.

Tracked examples:

Supported Platforms

  • macOS
  • Linux

Boundaries

  • intended to stay independently versioned and releasable
  • focused on state ergonomics, not full database or cache policy management
  • should stay useful on its own even if future higher-level app packages build on top

License

MIT

View source
1 # fgof-state
2
3 Persistent app and workspace state helpers for modern Fortran.
4
5 `fgof-state` is intended to be a small, standalone library for durable local
6 state, atomic save flows, and version-aware app data that CLI tools and
7 interactive apps keep hand-rolling.
8
9 It is part of the [FortranGoingOnForty lib-modules](https://github.com/FortranGoingOnForty/lib-modules)
10 catalog, but it is intended to stand on its own as a normal `fpm` package.
11
12 Current v1 target:
13
14 - stable state option, root, and document types
15 - predictable state-root resolution from explicit paths or XDG defaults
16 - atomic save or replace semantics for app and workspace state
17 - simple version-aware load or save flows with room for migrations later
18
19 Future scope:
20
21 - richer schema migration helpers
22 - backup or recovery helpers for state upgrades
23 - higher-level workspace and session persistence flows
24
25 ## Status
26
27 Sprint 04 is in place.
28
29 Tracked today:
30
31 - explicit state-root resolution from `root_dir`, `XDG_STATE_HOME`, or `HOME`
32 - namespace and scope-aware root layout
33 - document-path helpers and document resolution
34 - text-focused state save, load, and remove helpers
35 - `fgof-temp`-backed atomic replace semantics for saves
36 - side-effect-free reads and removes when state roots are missing
37 - version-aware state envelopes with explicit mismatch handling
38 - explicit `version_checked` / `version_matched` result semantics for version-aware loads
39 - malformed or unsupported state payloads rejected as version errors
40 - unreadable state files reported as `io` failures
41 - invalid version arguments rejected before filesystem writes
42 - tracked round-trip and version-mismatch examples
43 - POSIX root creation and existence checks
44 - focused scaffold coverage in `fpm test`
45 - CI on macOS and Ubuntu, including direct example execution
46
47 ## Why Use It
48
49 - app and workspace state shows up everywhere once tools grow past trivial size
50 - atomic persistence is easy to get subtly wrong
51 - a focused state layer builds naturally on the released temp and cache modules
52
53 ## Public API Shape
54
55 Primary modules:
56
57 - `fgof_state`
58 - `fgof_state_types`
59
60 Public types:
61
62 - `state_options`
63 - `state_root`
64 - `state_document`
65 - `state_text_result`
66
67 Public constants:
68
69 - `FGOF_STATE_OK`
70 - `FGOF_STATE_ERR_INVALID_OPTIONS`
71 - `FGOF_STATE_ERR_NOT_FOUND`
72 - `FGOF_STATE_ERR_IO`
73 - `FGOF_STATE_ERR_VERSION`
74 - `FGOF_STATE_ERR_INTERNAL`
75
76 Current public procedures:
77
78 - `clear_state_options`
79 - `clear_state_root`
80 - `clear_state_document`
81 - `clear_state_text_result`
82 - `ensure_state_root`
83 - `save_state_text`
84 - `load_state_text`
85 - `remove_state_document`
86 - `state_relative_path_for_name`
87 - `state_path_for_name`
88 - `resolve_state_document`
89 - `state_backend_name`
90 - `state_error_name`
91
92 Current semantics:
93
94 - `ensure_state_root()` resolves from explicit `root_dir`, or from `XDG_STATE_HOME` / `HOME` when `root_dir` is absent
95 - explicit `namespace` and `scope` values extend the resolved root path as validated path segments
96 - `create_root=.true.` creates state directories on demand; `create_root=.false.` requires the root to already exist
97 - `state_relative_path_for_name()` and `state_path_for_name()` expose the stable document path shape for valid document names
98 - `resolve_state_document()` returns the resolved root path, relative path, full path, and current presence state for a state document
99 - `save_state_text()` writes exact Fortran character payloads with same-directory atomic replacement through `fgof-temp`
100 - `load_state_text()` reads stored text back without creating missing roots as a side effect
101 - `remove_state_document()` removes stored state files without creating missing roots as a side effect
102 - `save_state_text()` stores a small internal format header plus a positive document version; the default version is `1`
103 - `load_state_text()` surfaces the stored version on `state_text_result%document%version`
104 - `state_text_result%version_checked` tells callers whether `expected_version=` was actually applied for that load
105 - `load_state_text(..., expected_version=...)` reports `version` errors explicitly when the stored document version does not match the caller expectation
106 - `state_text_result%version_matched` is only meaningful when `state_text_result%version_checked` is `.true.`
107 - unsupported or malformed state payloads also report `version` errors instead of pretending to be valid text
108 - unreadable state files report `io` errors during load
109 - missing documents report `not-found` for load or remove flows
110 - document names, namespaces, and scopes must not be empty, contain `/`, or be `.` / `..`
111
112 ## Build And Test
113
114 ```bash
115 fpm test
116 ```
117
118 That is the baseline verification command locally and in CI.
119
120 Tracked examples:
121
122 - [state_roundtrip_demo.f90](example/state_roundtrip_demo.f90)
123 - [state_version_demo.f90](example/state_version_demo.f90)
124
125 ## Supported Platforms
126
127 - macOS
128 - Linux
129
130 ## Boundaries
131
132 - intended to stay independently versioned and releasable
133 - focused on state ergonomics, not full database or cache policy management
134 - should stay useful on its own even if future higher-level app packages build on top
135
136 ## License
137
138 MIT