Add new entries method to hub module#417
Merged
Merged
Conversation
skhaz
approved these changes
Jul 3, 2026
Add a Lua read surface over the verified .wippy/vendor cache so a module can be fully inspected before install: hub.versions.open returns an owned package handle (fs.File-style, auto-closed via the resource store) exposing metadata, entries, resources, and a real fs handle over each embedded filesystem; flat hub.versions.resources / read_file cover one-shot reads. Adds hub.cache list/remove/prune (name+version addressed, lockfile as the pin set, mirroring pruneModuleArtifacts) so inspected-but-uninstalled artifacts can be reclaimed. Entry data is returned raw (placeholders/_env unresolved); the fs surface reuses the fs module (new fs.PushFS helper) rather than a parallel abstraction. Builds on #417's hub.versions.entries.
Remove hub.versions.entries/resources/read_file and their now-orphaned helpers; the package handle from hub.versions.open (metadata/entries/resources/fs/close) is the single read surface. Entries tests moved onto the handle.
16 tests over the handle and cache: arg/permission errors, download failure,
metadata, kind-filter (array + empty), raw data sealing (${env}/_env stay
literal), data type fidelity, empty/multi-file resources, fs readdir/stat/nested,
handle lifecycle (use-after-close, idempotent close), independent handles, and
cache list/remove/prune (pin refusal, force, dry-run, permissions) with on-disk checks.
… cleanup succeeds The read-surface tests opened a .wapp through hub.versions.open and relied on the frame-end AddCleanup to close it, but the test harness never closed the resource store, so the file stayed open. On Windows an open handle blocks t.TempDir removal, failing every open-based test. Attach a resource store to the test context and close it in cleanup (the production request-end path); add a Go-level test proving store close releases the handle.
The fs module resolves paths with the OS separator (filepath), but ReadOnlyFS wraps an fs.ReadDirFS whose io/fs contract requires forward-slash paths (io/fs.ValidPath rejects backslashes). On Windows a nested path like a\b reached the packfs and failed, so reading a module's embedded files via the hub package handle broke. Normalize with filepath.ToSlash at the adapter boundary (a no-op on Unix).
…parator fsapi.FS embeds the standard fs.StatFS/fs.ReadDirFS, so it follows the io/fs contract where paths are always forward-slash (io/fs.ValidPath rejects backslashes). The fs module's resolvePath used filepath.Join/Clean, producing backslash paths on Windows that broke any io/fs-backed filesystem (e.g. a wapp pack read through the hub package handle); the OS-backed directory fs only survived because it normalizes internally. Fix it at the source with path instead of filepath, and revert the earlier ReadOnlyFS workaround so the public api/fs stays untouched.
Type hub.versions.open's package handle (record with typed version/digest/packed fields and a metatable interface of metadata/entries/resources/fs/close) and the cache methods (typed arrays and records) instead of typ.Any; only genuinely dynamic values (entry data, meta values, the foreign fs handle) stay Any, as the registry module does. Add a manifest-consistency test that the handle is typed and lists exactly its methods, and register the hub/fs/api-fs packages in test.sh.
cache.remove now rejects a module/version whose joined path escapes the vendor directory, preventing os.RemoveAll from targeting arbitrary files. ensureCachedArtifact reuses a cache entry only when it both verifies and opens as a valid WAPP, so a corrupt entry that passes a no-op digest check is evicted and re-downloaded instead of permanently breaking reads.
parseWappRelPath split on the final hyphen, so a prerelease version like v1.2.3-beta.1 was reported as module orphan-v1.2.3 / version beta.1 in cache.list and prune. Anchor the split on the first hyphen whose suffix parses as a semantic version so hyphenated modules and prereleases both round-trip.
A version like "x/../other-v1.0.0" stays inside the vendor directory but normalizes onto a sibling module's artifact, so os.RemoveAll could delete another module (even a pinned one) after pin and permission checks ran only for the requested module. Require module and version to be single clean path components before building the target.
hub.versions.open/inspect passed an empty vendor dir and cached under the hard-coded .wippy/vendor, while hub.cache.* uses the lock-resolved vendor directory. Under a directories.modules override the two diverged and opened artifacts were invisible to cache list/prune/remove. Resolve the vendor dir the same way for both.
…oundary Left-to-right scanning over-consumed a module ending in a version-like segment (api-v2-v1.0.0 became module api / version v2-v1.0.0). Scanning hyphens from the right takes the shortest valid version suffix, which keeps prereleases intact and classifies hyphenated modules correctly.
artifactCachePath built the org/module cache path from an unvalidated version (including a registry-returned one), so a version with separators or ".." could steer DownloadToFile to write outside the vendor directory. Require clean module/version components and verify the target stays within the cache, matching the cache.remove guards.
resolvePath returns io/fs forward-slash paths regardless of OS, but the test helper converted the expected value with filepath.FromSlash, so on Windows it compared against backslash-separated paths and the TestResolvePath cases failed. Compare the forward-slash expectation directly.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Reason for This PR
Added a new entries method for retrieving module entries. This can be used to implement module code scanning before installation