New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resource loading #135
Resource loading #135
Conversation
d1a0f6e
to
81d6116
Compare
This implements a "magic" module '@jkcfg/std/resource'. It's magic because it's generated each time it's imported, so that it can take into account the path of the importing module (known at import time, and not thereafter). The implementations is this: create a module that embeds the base path of the module, and exports a procedure that does reads relative to the base path. This has some flaws: - at present, jk (v8worker2, really) gives imports using the same specifier (in this case `@jkcfg/std/resource`) the same module, which is not much use for magic modules. - it relies on the module base path being readable (if you change the input path when you run jk, it might not be)
This commit adds a test that resource() can succeed even if the module directory is not under the input directory. The test does not pass, since all reads are currently required to be under the input directory. It also corrects the guard against reading outside of the input directory: it's possible for os/path/filepath.Rel to return a relative path that starts with parent directories, i.e., with `..`.
Just using std.read() for resources won't work in general, because the desired path may not be under the input directory (and reads are restricted to paths under the read directory). To enable reads from module directories, while keeping the guard against reading outside the allowed paths, keep track of each module that imports `@jkcfg/std/resource' and look up the module path when its `resource` procedure is called, to use as a base path.
81d6116
to
d07e6c4
Compare
To be able to identify the base path of a resource read, I added a `module` option to `read`. That is now "generally available", meaning any read might include it, if it can guess a module hash, and read from some other module's base path. To prevent abuse of this mechanism, salt the module hash using random bytes generated when starting up. The randomness does not hinder repeatability, since the hashes are opaque and only used in the scope of a run anyway.
I totally misread the test case :) all good :) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
\o/ this looks awesome to me!
// as generating the magic modules when they are imported. | ||
type ModuleResources struct { | ||
// module hash -> basePath for resource reads | ||
modules map[string]string |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can't manipulate this map from different goroutines, so we indeed don't need locking?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
At present it won't happen, but I could be defensive and put a mutex on it
fed3321
to
a2bd768
Compare
This implements a "magic" module '@jkcfg/std/resource'. It's magic
because it's generated each time it's imported, so that it can take
into account the path of the importing module (known at import time,
and not thereafter).
The implementation is this:
module
for specifying a module to use as the base path (a missing value means use the input directory);@jkcfg/std/resource
is imported, hash the current import base path (i.e., the directory of the importing module), then load module code exporting a procedure that reads using the hash.This has some flaws:at present, jk (v8worker2, really) gives imports using the samespecifier (in this case
@jkcfg/std/resource
) the same module,which is not much use for magic modules.
it relies on the module base path being readable (if you change theinput path when you run jk, it might not be)
(EDIT: strike out flaws, which have been excised, and explain how module base paths are identified.)