2018-02-11 22:18:07 +00:00
|
|
|
config = require "locator_config"
|
|
|
|
|
|
|
|
import insert, sort from table
|
|
|
|
|
|
|
|
-- locates and returns a module, or errors
|
2018-02-12 00:50:01 +00:00
|
|
|
-- if a path is specified, it will be checked before other paths
|
|
|
|
-- checks the project root, then each path specified in locator_config
|
|
|
|
try_require = (name, path) ->
|
|
|
|
if path
|
|
|
|
ok, value = pcall -> require "#{path}.#{name}"
|
2018-02-11 22:18:07 +00:00
|
|
|
return value if ok
|
|
|
|
|
2018-02-12 00:50:01 +00:00
|
|
|
ok, value = pcall -> require name
|
2018-02-11 22:18:07 +00:00
|
|
|
return value if ok
|
|
|
|
|
|
|
|
for item in *config
|
2018-02-12 00:50:01 +00:00
|
|
|
ok, value = pcall -> require "#{item.path}.#{name}"
|
2018-02-11 22:18:07 +00:00
|
|
|
return value if ok
|
|
|
|
|
2018-02-12 00:50:01 +00:00
|
|
|
error "locator could not find '#{name}'"
|
2018-02-11 22:18:07 +00:00
|
|
|
|
|
|
|
-- works like Lapis's autoload, but
|
|
|
|
-- includes trying sub-application paths & can be called to access a value
|
|
|
|
autoload = (path, tab={}) ->
|
|
|
|
return setmetatable tab, {
|
|
|
|
__call: (t, name) ->
|
|
|
|
t[name] = try_require name, path
|
|
|
|
return t[name]
|
|
|
|
__index: (t, name) ->
|
|
|
|
t[name] = try_require name, path
|
|
|
|
return t[name]
|
|
|
|
}
|
|
|
|
|
|
|
|
-- pass your migrations, it returns them + all sub-application migrations
|
|
|
|
-- (legacy) see example config for how to specify to not include early migrations
|
2018-02-11 22:59:37 +00:00
|
|
|
make_migrations = (app_migrations={}) ->
|
2018-02-11 22:18:07 +00:00
|
|
|
for item in *config
|
|
|
|
ok, migrations = pcall -> require "#{item.path}.migrations"
|
|
|
|
if ok
|
|
|
|
sorted = {}
|
|
|
|
for m in pairs migrations
|
|
|
|
insert sorted, m
|
|
|
|
sort sorted
|
|
|
|
for i in *sorted
|
|
|
|
-- only allow migrations after specified config value, or if no 'after' is specified
|
|
|
|
if (item.migrations and ((item.migrations.after and i > item.migrations.after) or not item.migrations.after)) or not item.migrations
|
|
|
|
-- if your migrations and theirs share a value, combine them
|
|
|
|
if app_fn = app_migrations[i]
|
|
|
|
app_migrations[i] = (...) ->
|
|
|
|
app_fn(...)
|
|
|
|
migrations[i](...)
|
|
|
|
-- else just add them
|
|
|
|
else
|
|
|
|
app_migrations[i] = migrations[i]
|
|
|
|
|
|
|
|
return app_migrations
|
|
|
|
|
2018-02-12 00:50:01 +00:00
|
|
|
-- return access to autoload and make_migrations functions,
|
|
|
|
-- a self-reference, and metamethods for getting autoloaders
|
|
|
|
locator = {
|
|
|
|
locate: locator, :autoload, :make_migrations
|
|
|
|
}
|
|
|
|
return setmetatable locator, {
|
|
|
|
__call: (t, here="") ->
|
2018-02-11 22:18:07 +00:00
|
|
|
if "init" == here\sub -4
|
|
|
|
here = here\sub 1, -6
|
2018-02-12 00:50:01 +00:00
|
|
|
unless here\len! > 0
|
2018-02-11 22:18:07 +00:00
|
|
|
here = ""
|
|
|
|
return autoload here
|
|
|
|
|
|
|
|
__index: (t, name) ->
|
|
|
|
t[name] = autoload name
|
|
|
|
return t[name]
|
|
|
|
}
|