feat: first-draft preview-capable zosstorage
- CLI: add topology selection (-t/--topology), preview flags (--show/--report), and removable policy override (--allow-removable) (src/cli/args.rs) - Config: built-in sensible defaults; deterministic overlays for logging, fstab, removable, topology (src/config/loader.rs) - Device: discovery via /proc + /sys with include/exclude regex and removable policy (src/device/discovery.rs) - Idempotency: detection via blkid; safe emptiness checks (src/idempotency/mod.rs) - Partition: topology-driven planning (Single, DualIndependent, BtrfsRaid1, SsdHddBcachefs) (src/partition/plan.rs) - FS: planning + creation (mkfs.vfat, mkfs.btrfs, bcachefs format) and UUID capture via blkid (src/fs/plan.rs) - Orchestrator: pre-flight with preview JSON (disks, partition_plan, filesystems_planned, mount scheme). Skips emptiness in preview; supports stdout+file (src/orchestrator/run.rs) - Util/Logging/Types/Errors: process execution, tracing, shared types (src/util/mod.rs, src/logging/mod.rs, src/types.rs, src/errors.rs) - Docs: add README with exhaustive usage and preview JSON shape (README.md) Builds and unit tests pass: discovery, util, idempotency helpers, and fs parser tests.
This commit is contained in:
123
docs/DEV_WORKFLOW.md
Normal file
123
docs/DEV_WORKFLOW.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# Modular Development Workflow and Traceability
|
||||
|
||||
Goal
|
||||
- Enable incremental implementation without re-reading the entire codebase each time.
|
||||
- Make module changes discoverable via grep and predictable locations.
|
||||
- Keep a single source of truth for the API surface, invariants, and extension points.
|
||||
|
||||
Core Principles
|
||||
1) Contract-first per module
|
||||
- API signatures and responsibilities are documented in [docs/API-SKELETONS.md](docs/API-SKELETONS.md) and mirrored by crate modules:
|
||||
- [src/types.rs](src/types.rs)
|
||||
- [fn load_and_merge()](src/config/loader.rs:1), [fn validate()](src/config/loader.rs:1)
|
||||
- [fn from_args()](src/cli/args.rs:1)
|
||||
- [struct LogOptions](src/logging/mod.rs:1), [fn init_logging()](src/logging/mod.rs:1)
|
||||
- [fn discover()](src/device/discovery.rs:1)
|
||||
- [fn plan_partitions()](src/partition/plan.rs:1), [fn apply_partitions()](src/partition/plan.rs:1)
|
||||
- [fn plan_filesystems()](src/fs/plan.rs:1), [fn make_filesystems()](src/fs/plan.rs:1)
|
||||
- [fn plan_mounts()](src/mount/ops.rs:1), [fn apply_mounts()](src/mount/ops.rs:1), [fn maybe_write_fstab()](src/mount/ops.rs:1)
|
||||
- [const REPORT_VERSION](src/report/state.rs:1), [fn build_report()](src/report/state.rs:1), [fn write_report()](src/report/state.rs:1)
|
||||
- [struct Context](src/orchestrator/run.rs:1), [fn run()](src/orchestrator/run.rs:1)
|
||||
- [fn detect_existing_state()](src/idempotency/mod.rs:1), [fn is_empty_disk()](src/idempotency/mod.rs:1)
|
||||
- [struct CmdOutput](src/util/mod.rs:1), [fn which_tool()](src/util/mod.rs:1), [fn run_cmd()](src/util/mod.rs:1), [fn run_cmd_capture()](src/util/mod.rs:1), [fn udev_settle()](src/util/mod.rs:1)
|
||||
|
||||
2) Grep-able region markers in code
|
||||
- Every module contains the following optional annotated regions:
|
||||
- // REGION: API
|
||||
- // REGION: EXTENSION_POINTS
|
||||
- // REGION: SAFETY
|
||||
- // REGION: ERROR_MAPPING
|
||||
- // REGION: TODO
|
||||
- Example snippet to add near top of a module:
|
||||
// REGION: API
|
||||
// api: device::discover(filter: &DeviceFilter) -> Result<Vec<Disk>>
|
||||
// api: device::DeviceProvider
|
||||
// REGION: API-END
|
||||
- These must be kept concise, one-liners per function/trait/struct; they act as a quick index for search.
|
||||
|
||||
3) Stable identifiers for cross-references
|
||||
- Use short identifiers in comments to reference public items:
|
||||
- api: module::item
|
||||
- ext: module::hook_or_trait
|
||||
- safety: module::invariant_name
|
||||
- errmap: module::error_path
|
||||
- This allows quick discovery via regex: grep -R "api: device::" src/
|
||||
|
||||
4) Single source of truth for API surface
|
||||
- Keep high-level API in [docs/API-SKELETONS.md](docs/API-SKELETONS.md) as canonical index. After adding/removing a public function or type, update this file.
|
||||
- Add a short note in [docs/SPECS.md](docs/SPECS.md) if behavior or invariants change.
|
||||
|
||||
5) Architectural decisions recorded as ADRs
|
||||
- Use docs/adr/NNNN-title.md to document decisions (context, decision, consequences).
|
||||
- Start with [docs/adr/0001-modular-workflow.md](docs/adr/0001-modular-workflow.md) (added alongside this doc).
|
||||
- Link ADRs from [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) when they supersede or refine prior guidance.
|
||||
|
||||
6) Module ownership and boundaries
|
||||
- Add a “Module Responsibilities” section in each module’s header doc comment summarizing scope and non-goals.
|
||||
- Example references:
|
||||
- [src/device/discovery.rs](src/device/discovery.rs)
|
||||
- [src/partition/plan.rs](src/partition/plan.rs)
|
||||
- [src/fs/plan.rs](src/fs/plan.rs)
|
||||
- [src/mount/ops.rs](src/mount/ops.rs)
|
||||
- [src/report/state.rs](src/report/state.rs)
|
||||
|
||||
7) Invariants and safety notes
|
||||
- For code that must uphold safety or idempotency invariants, annotate with:
|
||||
// SAFETY: explanation
|
||||
// IDEMPOTENCY: explanation
|
||||
- Example locations:
|
||||
- [fn apply_partitions()](src/partition/plan.rs:1) must enforce empty-disks rule when configured.
|
||||
- [fn make_filesystems()](src/fs/plan.rs:1) must not run if partitioning failed.
|
||||
|
||||
8) Error mapping consistency
|
||||
- Centralize conversions to [enum Error](src/errors.rs:1). When calling external tools, wrap failures into Error::Tool with stderr captured.
|
||||
- Annotate mapping areas with:
|
||||
// ERROR: mapping external failure to Error::Tool
|
||||
|
||||
9) Module-local CHANGELOG entries
|
||||
- Keep a single CHANGELOG in the repo root, plus module-local “Changes” sections appended on each module top comment (short bullets).
|
||||
- Cross-link to the ADR when relevant.
|
||||
|
||||
10) Task-level breadcrumbs
|
||||
- For multi-step features, add a short progress marker at top of relevant modules:
|
||||
// TODO(KILO): feature-X step 2/4 – parsing args done; next implement validation
|
||||
- Summary of active tasks can also live in docs/SPECS.md under “In-Progress Work”.
|
||||
|
||||
11) Example configs and fixtures
|
||||
- Keep comprehensive examples in:
|
||||
- [config/zosstorage.example.yaml](config/zosstorage.example.yaml)
|
||||
- Add minimal example variants if needed for tests (future):
|
||||
- examples/config/minimal.yaml
|
||||
- examples/config/dual-btrfs.yaml
|
||||
- examples/config/ssd-hdd-bcachefs.yaml
|
||||
|
||||
12) “Golden paths” for resuming work
|
||||
- If resuming work later:
|
||||
- Read module headers for responsibilities
|
||||
- Grep for REGION markers: API / TODO / SAFETY / ERROR_MAPPING
|
||||
- Check [docs/API-SKELETONS.md](docs/API-SKELETONS.md) for contract changes
|
||||
- Check latest ADRs in docs/adr/
|
||||
- Check [docs/SPECS.md](docs/SPECS.md) and the “In-Progress Work” section (if used)
|
||||
|
||||
Checklist for adding a new feature
|
||||
- Update contracts:
|
||||
- Add or modify function/type signatures in code and reflect in [docs/API-SKELETONS.md](docs/API-SKELETONS.md)
|
||||
- Add REGION: API one-liners for the new items
|
||||
- Update invariants:
|
||||
- Add REGION: SAFETY notes if needed
|
||||
- Update specs:
|
||||
- Document behavior in [docs/SPECS.md](docs/SPECS.md)
|
||||
- If it is a long-term decision, add an ADR under docs/adr/
|
||||
- Add examples if config or output formats change
|
||||
- Update [config/zosstorage.example.yaml](config/zosstorage.example.yaml) or add a new example file
|
||||
- Keep error mapping and logging consistent:
|
||||
- Ensure any external tool calls map errors to [enum Error](src/errors.rs:1)
|
||||
- Run cargo build and update any broken references
|
||||
|
||||
Optional automation (future)
|
||||
- A simple “index check” script (cargo xtask) could validate:
|
||||
- All public items referenced under REGION: API appear in [docs/API-SKELETONS.md](docs/API-SKELETONS.md)
|
||||
- No broken module references
|
||||
- REGION markers are well-formed
|
||||
|
||||
By following these conventions, changes stay localized and discoverable. A contributor (human or assistant) can quickly locate relevant areas by scanning module headers, REGION markers, and the centralized API/docs without re-reading the entire tree.
|
||||
Reference in New Issue
Block a user