|
root / docs / PACKAGE_FORMAT_V2_TODO.md
PACKAGE_FORMAT_V2_TODO.md markdown 116 lines 7.0 KB

Package Format v2 — Task List

Design: docs/PACKAGE_FORMAT_V2_DESIGN.md
Target: Coral v0.3
Date: 2026-03-07
Requires: Reef >= 0.5.0


Phase 1: mtree module and manifest generation — COMPLETE

  • Create src/util/mtree.reef module with ManifestEntry type
  • Implement parse_manifest() — line-oriented parser, split on space, extract key=value pairs
  • Implement generate_manifest() — walk directory tree using fs.stat, fs.perm, fs.link.readlink(), checksum.sha256_file()
  • Implement accessor functions: entry_type, entry_path, entry_mode, entry_sha256, entry_link, entry_uname, entry_gname
  • Handle sort order: lexicographic by path so dirs precede their contents
  • Skip metadata files (.PKGINFO, .MANIFEST, .CONFIG, .SCRIPTS/) during generation
  • Update build.reef: replace generate_footprint() with generate_manifest() using new mtree module
  • Rename output file from .FOOTPRINT to .MANIFEST in build output
  • Test: build a package, verify .MANIFEST output contains correct types, modes, ownership, checksums
  • Test: parse a generated manifest back and verify round-trip correctness

Phase 2: fs.ops-based installer — COMPLETE

  • Rewrite install_files() in package.reef to parse .MANIFEST instead of .FOOTPRINT
  • Implement dir install: dir.create_dir_all(), fs.perm.chmod(), fs.perm.chown()
  • Implement file install: fs.ops.copy_file_preserve(), fs.perm.chmod(), fs.perm.chown()
  • Implement symlink install: remove conflicting target, fs.link.symlink()
  • Add post-copy sha256 verification against manifest checksum
  • Integrate config file checksum logic (see Phase 2b below)
  • Remove rsync call from install_files()
  • Remove symlink conflict prep_cmd shell-out (handle inline during manifest walk)
  • Error handling: stop on any failed file operation
  • Update read_footprint() to read .MANIFEST first, fall back to .FOOTPRINT
  • Update register_from_extract_dir() to store manifest.mtree in database
  • Update remove_files() to use fs.ops.remove_file instead of shell-outs
  • Add remove_files_manifest() for manifest-driven removal with explicit directory tracking
  • Clean up stale rsync comments in install.reef
  • Test: install a package to a test root, verify all files/dirs/symlinks match manifest
  • Test: install package with setuid binary (mode=4755), verify mode preserved
  • Test: install package with symlinks, verify targets correct

Phase 2b: Config file checksum logic — COMPLETE

  • Update install_config_file() to accept manifest sha256 and stored sha256 parameters
  • On fresh install: copy file normally
  • On upgrade (file exists, matches old checksum): overwrite with new version
  • On upgrade (file exists, differs from old checksum): install as .pkg-new, preserve user's file
  • Remove old content-comparison logic (str.equals(src_content, dest_content))
  • On remove: skip config files where installed sha256 differs from package sha256
  • Test: fresh install places config file and records checksum
  • Test: upgrade with unmodified config overwrites cleanly
  • Test: upgrade with user-modified config installs .pkg-new and preserves original

Phase 3: Enhanced .PKGINFO — COMPLETE

  • Add runtime_deps, build_deps, runtime_deps_count, build_deps_count fields to PackageInfo type in types.reef
  • Update new_package_info() factory to initialize new fields
  • Update generate_pkginfo() in build.reef to emit [dependencies] section
  • Write runtime array from ctx.port.deps.runtime
  • Write build array from ctx.port.deps.build
  • Skip [dependencies] section if both arrays are empty
  • Update read_pkginfo() in package.reef to parse [dependencies] section
  • Handle legacy packages without [dependencies] gracefully
  • Add parse_toml_array() helper to package.reef
  • Handle version constraint syntax in dependency strings (>=, <=, >, <, =)
  • Add version comparison utility for constraint checking
  • Test: build a package with dependencies, verify .PKGINFO contains correct [dependencies]
  • Test: parse .PKGINFO with dependencies and verify fields populated

Phase 4: Script model cleanup — COMPLETE

  • Remove .reef script type from run_script() in package.reef
  • Remove .reef script type from run_stored_script() in package.reef
  • Change .sh invocation from sh to zsh in run_script()
  • Change .sh invocation from sh to zsh in run_stored_script()
  • Update script search order: try .sh first, then bare executable
  • Add pre-upgrade.sh / post-upgrade.sh hook support
  • Pass $VERSION argument to pre-install, post-install, pre-remove, post-remove
  • Pass $OLD_VERSION $NEW_VERSION arguments to pre-upgrade, post-upgrade
  • Abort install/remove/upgrade if pre-* hook exits non-zero
  • Log warning (don't abort) if post-* hook exits non-zero
  • Store upgrade scripts in database alongside remove scripts at install time
  • Implement upgrade flow: pre-upgrade → remove old files → install new files → post-upgrade
  • Test: package with pre-install that exits 0 — install proceeds
  • Test: package with pre-install that exits 1 — install aborts
  • Test: package with post-install that exits 1 — install completes with warning
  • Test: upgrade with pre-upgrade/post-upgrade scripts, verify version args passed

Phase 5: Removal and verify — COMPLETE

  • Rewrite remove_files() to use fs.ops instead of shell-outs (done in Phase 2)
  • Add remove_files_manifest() with explicit directory tracking (done in Phase 2)
  • Respect config file protection on remove (skip user-modified configs) (done in Phase 2b)
  • Implement coral verify <pkg> command
    • Read stored manifest from database
    • For each file entry: check exists, compare sha256, compare mode/ownership
    • For each symlink entry: check exists, verify link target
    • For each dir entry: check exists
    • Report: missing files, checksum mismatches, permission changes, broken symlinks
  • Test: remove a package, verify all files deleted and empty dirs cleaned up
  • Test: remove a package with user-modified config, verify config preserved
  • Test: verify a clean install — all files pass
  • Test: verify after modifying a file — checksum mismatch reported

Cleanup

  • Remove generate_footprint() from build.reef (replaced by generate_manifest())
  • Update read_footprint() to read .MANIFEST via mtree parser (with .FOOTPRINT fallback)
  • Update verify_package() to check for .MANIFEST or .FOOTPRINT
  • Remove rsync from install path (only remains in repo.reef mirror command)
  • Clean up rsync comments in install.reef
  • Update docs/GUIDE.md — fix .reef references, sh→zsh, .pkg→.pkg-new, add verify command, add version constraints, add upgrade scripts