Skip to content

Add new entries method to hub module#417

Merged
wolfy-j merged 17 commits into
mainfrom
feat/module-entries
Jul 4, 2026
Merged

Add new entries method to hub module#417
wolfy-j merged 17 commits into
mainfrom
feat/module-entries

Conversation

@msmakouz

@msmakouz msmakouz commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Reason for This PR

Added a new entries method for retrieving module entries. This can be used to implement module code scanning before installation

@msmakouz msmakouz requested review from skhaz and wolfy-j July 3, 2026 17:44
@msmakouz msmakouz self-assigned this 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.
wolfy-j added 15 commits July 3, 2026 21:01
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.
@wolfy-j wolfy-j merged commit 0ef8e00 into main Jul 4, 2026
4 checks passed
@wolfy-j wolfy-j deleted the feat/module-entries branch July 4, 2026 16:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants