mtots_core 0.1.2

Core implementation of the mtots scripting language
Documentation
# cargo run libs/ -m a.test -- folder_with_test_sources/ [package_to_test]
# import a.os
# import a.os::PIPE
# import a.os::UTF8
# import a.os::Process
# import a.os::Path
import a.fs
import a.env

def main() {
    args = env.args()
    if args.len() is 1 {
        [root_dir] = args
        test_pkg = ''
    } else {
        [root_dir, test_pkg] = args
    }
    run(root_dir, test_pkg)
}

def run(root_dir, test_pkg=nil) {
    if test_pkg is nil { test_pkg = '' }
    root_dir = fs.canon(root_dir)
    for module_name in _get_module_names(root_dir, test_pkg) {
        print(module_name)
        module = __import(module_name)
        keys = getattrs(module).filter(def(k) = k.starts_with('__test_'))
        if keys {
            for attr in keys {
                attr_str = str(attr)
                print('  ' + attr_str)
                getattr(module, attr)()
            }
        } else {
            print('  no tests')
        }
    }
}

def* _get_module_names(root, package_name) {
    for [dirpath, _dirnames, filenames] in fs.walk(
            fs.join(root, package_name.replace('.', fs.sep)),
            sort=true,
    ) {
        if filenames.has('__init.u') {
            yield str(fs.relpath(root, dirpath)).replace(fs.sep, '.')
        }
        for filename in sorted(filenames) {
            filepath = fs.join(dirpath, filename)
            if filename.ends_with('.u') and filename != '__init.u' {
                yield str(fs.relpath(root, filepath)).rstrip('.u').replace(fs.sep, '.')
            }
        }
    }
}

if __name == __main() {
    main()
}