Refactor: take some functions out of job_compilers.Service
Take some functions out of the `Service` struct, as they are more or less standalone anyway. This will also make it easier later to make things thread-safe, as that'll become important when files can get live-reloaded.
This commit is contained in:
parent
d5c527209f
commit
201236cf46
@ -59,7 +59,9 @@ func Load(ts TimeService) (*Service, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
staticFileLoader := func(path string) ([]byte, error) {
|
staticFileLoader := func(path string) ([]byte, error) {
|
||||||
content, err := compiler.loadScriptBytes(scriptsFS, path)
|
// TODO: this should try different filesystems, once we allow loading from
|
||||||
|
// disk as well.
|
||||||
|
content, err := loadScriptBytes(scriptsFS, path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// The 'require' module uses this to try different variations of the path
|
// The 'require' module uses this to try different variations of the path
|
||||||
// in order to find it (without .js, with .js, etc.), so don't log any of
|
// in order to find it (without .js, with .js, etc.), so don't log any of
|
||||||
|
@ -26,24 +26,32 @@ func (s *Service) loadScripts() error {
|
|||||||
return fmt.Errorf("failed to find embedded 'scripts' directory: %w", err)
|
return fmt.Errorf("failed to find embedded 'scripts' directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.loadScriptsFrom(scriptsSubFS)
|
compilers, err := loadScriptsFrom(scriptsSubFS)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
s.compilers = compilers
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadScriptsFrom iterates over all given directory entries, compiles the
|
// loadScriptsFrom iterates over all given directory entries, compiles the
|
||||||
// files, and stores the result into `s.compilers`.
|
// files, and stores the result into `s.compilers`.
|
||||||
func (s *Service) loadScriptsFrom(filesystem fs.FS) error {
|
func loadScriptsFrom(filesystem fs.FS) (map[string]Compiler, error) {
|
||||||
dirEntries, err := fs.ReadDir(filesystem, ".")
|
dirEntries, err := fs.ReadDir(filesystem, ".")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to find scripts in %v: %w", filesystem, err)
|
return nil, fmt.Errorf("failed to find scripts in %v: %w", filesystem, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
compilers := map[string]Compiler{}
|
||||||
|
|
||||||
for _, dirEntry := range dirEntries {
|
for _, dirEntry := range dirEntries {
|
||||||
filename := dirEntry.Name()
|
filename := dirEntry.Name()
|
||||||
if !strings.HasSuffix(filename, ".js") {
|
if !strings.HasSuffix(filename, ".js") {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
script_bytes, err := s.loadScriptBytes(filesystem, filename)
|
script_bytes, err := loadScriptBytes(filesystem, filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Str("filename", filename).Msg("failed to read script")
|
log.Error().Err(err).Str("filename", filename).Msg("failed to read script")
|
||||||
continue
|
continue
|
||||||
@ -64,7 +72,7 @@ func (s *Service) loadScriptsFrom(filesystem fs.FS) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
jobTypeName := filenameToJobType(filename)
|
jobTypeName := filenameToJobType(filename)
|
||||||
s.compilers[jobTypeName] = Compiler{
|
compilers[jobTypeName] = Compiler{
|
||||||
jobType: jobTypeName,
|
jobType: jobTypeName,
|
||||||
program: program,
|
program: program,
|
||||||
filename: filename,
|
filename: filename,
|
||||||
@ -76,10 +84,10 @@ func (s *Service) loadScriptsFrom(filesystem fs.FS) error {
|
|||||||
Msg("loaded script")
|
Msg("loaded script")
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return compilers, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) loadScriptBytes(filesystem fs.FS, path string) ([]byte, error) {
|
func loadScriptBytes(filesystem fs.FS, path string) ([]byte, error) {
|
||||||
file, err := filesystem.Open(path)
|
file, err := filesystem.Open(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("failed to open embedded script: %w", err)
|
return nil, fmt.Errorf("failed to open embedded script: %w", err)
|
||||||
@ -93,7 +101,7 @@ func filenameToJobType(filename string) string {
|
|||||||
return strings.ReplaceAll(stem, "_", "-")
|
return strings.ReplaceAll(stem, "_", "-")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Service) newGojaVM() *goja.Runtime {
|
func newGojaVM(registry *require.Registry) *goja.Runtime {
|
||||||
vm := goja.New()
|
vm := goja.New()
|
||||||
vm.SetFieldNameMapper(goja.UncapFieldNameMapper())
|
vm.SetFieldNameMapper(goja.UncapFieldNameMapper())
|
||||||
|
|
||||||
@ -111,7 +119,7 @@ func (s *Service) newGojaVM() *goja.Runtime {
|
|||||||
mustSet("formatTimestampLocal", jsFormatTimestampLocal)
|
mustSet("formatTimestampLocal", jsFormatTimestampLocal)
|
||||||
|
|
||||||
// Pre-import some useful modules.
|
// Pre-import some useful modules.
|
||||||
s.registry.Enable(vm)
|
registry.Enable(vm)
|
||||||
mustSet("author", require.Require(vm, "author"))
|
mustSet("author", require.Require(vm, "author"))
|
||||||
mustSet("path", require.Require(vm, "path"))
|
mustSet("path", require.Require(vm, "path"))
|
||||||
mustSet("process", require.Require(vm, "process"))
|
mustSet("process", require.Require(vm, "process"))
|
||||||
@ -127,7 +135,7 @@ func (s *Service) compilerForJobType(jobTypeName string) (*VM, error) {
|
|||||||
return nil, ErrJobTypeUnknown
|
return nil, ErrJobTypeUnknown
|
||||||
}
|
}
|
||||||
|
|
||||||
vm := s.newGojaVM()
|
vm := newGojaVM(s.registry)
|
||||||
if _, err := vm.RunProgram(program.program); err != nil {
|
if _, err := vm.RunProgram(program.program); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -8,26 +8,23 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func TestLoadScriptsFrom_skip_nonjs(t *testing.T) {
|
func TestLoadScriptsFrom_skip_nonjs(t *testing.T) {
|
||||||
s := Service{}
|
|
||||||
|
|
||||||
thisDirFS := os.DirFS(".")
|
thisDirFS := os.DirFS(".")
|
||||||
assert.NoError(t, s.loadScriptsFrom(thisDirFS), "input without JS files should not cause errors")
|
compilers, err := loadScriptsFrom(thisDirFS)
|
||||||
assert.Empty(t, s.compilers)
|
assert.NoError(t, err, "input without JS files should not cause errors")
|
||||||
|
assert.Empty(t, compilers)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLoadScriptsFrom_on_disk_js(t *testing.T) {
|
func TestLoadScriptsFrom_on_disk_js(t *testing.T) {
|
||||||
s := Service{
|
|
||||||
compilers: map[string]Compiler{},
|
|
||||||
}
|
|
||||||
|
|
||||||
scriptsFS := os.DirFS("scripts-for-unittest")
|
scriptsFS := os.DirFS("scripts-for-unittest")
|
||||||
assert.NoError(t, s.loadScriptsFrom(scriptsFS))
|
compilers, err := loadScriptsFrom(scriptsFS)
|
||||||
|
|
||||||
|
assert.NoError(t, err)
|
||||||
expectKeys := map[string]bool{
|
expectKeys := map[string]bool{
|
||||||
"echo-and-sleep": true,
|
"echo-and-sleep": true,
|
||||||
"simple-blender-render": true,
|
"simple-blender-render": true,
|
||||||
// Should NOT contain an entry for 'empty.js'.
|
// Should NOT contain an entry for 'empty.js'.
|
||||||
}
|
}
|
||||||
assert.Equal(t, expectKeys, keys(s.compilers))
|
assert.Equal(t, expectKeys, keys(compilers))
|
||||||
}
|
}
|
||||||
|
|
||||||
// keys returns the set of keys of the mapping.
|
// keys returns the set of keys of the mapping.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user