glob

    A glob library for MoonBit, supporting wildcard pattern matching on file paths.

    glob
    path
    wildcard
    pattern
    matching
    Download zip
    Author
    Version
    0.1.9
    License
    MIT
    Last updated
    8 days ago
    Downloads
    376

    #Glob

    ci coverage

    A small path-aware glob matcher for MoonBit.

    It supports ?, *, and **:

    • ? matches exactly one character
    • * matches inside a single path segment
    • ** matches across path separators

    Bracket expressions such as [abc] are only validated by @glob.is_valid_pattern; they are not matched specially yet.

    #Quick Start

    ///|
    test {
    assert_eq(@glob.glob("*.txt", "notes.txt"), true)
    assert_eq(@glob.glob("src/*.mbt", "src/main.mbt"), true)
    assert_eq(@glob.glob("src/*.mbt", "src/lib/main.mbt"), false)
    assert_eq(@glob.glob("src/**/*.mbt", "src/lib/main.mbt"), true)
    }

    #Bulk Matching

    ///|
    test {
    let files = ["README.md", "src/main.mbt", "src/lib/util.mbt"]
    assert_eq(@glob.glob_match_any("src/**", files), true)
    assert_eq(@glob.glob_filter("src/**/*.mbt", files), ["src/lib/util.mbt"])
    assert_eq(@glob.match_any_pattern(["*.md", "**/*.mbt"], "README.md"), true)
    }

    #Helpers

    ///|
    test {
    assert_eq(@glob.is_valid_pattern("[abc]*.txt"), true)
    assert_eq(@glob.is_valid_pattern("[abc*.txt"), false)
    assert_eq(@glob.escape_glob("file?.txt"), "file\\?.txt")
    }

    escape_glob

    fn escape_glob(text : String) -> String

    Prefix common glob metacharacters in text with backslashes.

    This helper is useful when you want a readable escaped representation of a pattern fragment or when interoperating with tools that treat backslashes as escapes. The current matcher does not interpret backslashes specially.

    Example

    test {
    assert_eq(@glob.escape_glob("file*.txt"), "file\\*.txt")
    assert_eq(@glob.escape_glob("test?[1].log"), "test\\?\\[1\\].log")
    assert_eq(@glob.escape_glob("plain.txt"), "plain.txt")
    }

    get_char

    fn get_char(s : String, index : Int) -> Char?

    Safely read one character from s by zero-based index.

    This helper returns None instead of raising when the index is out of bounds.

    Example

    test {
    assert_true(@glob.get_char("moon", 0) == Some('m'))
    assert_true(@glob.get_char("moon", 3) == Some('n'))
    assert_true(@glob.get_char("moon", 4) == None)
    }

    glob

    fn glob(pattern : String, text : String) -> Bool

    Match one glob pattern against one text path.

    This is the main public entry point for the package.

    Supported syntax:

    • * matches zero or more non-separator characters
    • ** matches zero or more characters, including separators
    • ? matches exactly one character

    Bracket expressions such as [abc] are validated by is_valid_pattern, but they are not matched specially yet.

    Example

    test {
    assert_eq(@glob.glob("file?.log", "file1.log"), true)
    assert_eq(@glob.glob("**/*.md", "docs/api/readme.md"), true)
    assert_eq(@glob.glob("*.jpg", "images/logo.png"), false)
    }

    glob_filter

    fn glob_filter(pattern : String, paths : Array[String]) -> Array[String]

    Return a new array containing only the paths that match pattern.

    The original array is left unchanged.

    Example

    test {
    let files = ["README.md", "src/main.mbt", "src/lib/util.mbt"]
    assert_true(@glob.glob_filter("src/*.mbt", files) == ["src/main.mbt"])
    assert_true(@glob.glob_filter("src/**/*.mbt", files) == ["src/lib/util.mbt"])
    }

    glob_match_any

    fn glob_match_any(pattern : String, paths : Array[String]) -> Bool

    Return whether any path in paths matches pattern.

    The function stops at the first match.

    Example

    test {
    let files = ["README.md", "src/main.mbt", "test/main_test.mbt"]
    assert_eq(@glob.glob_match_any("**/*.mbt", files), true)
    assert_eq(@glob.glob_match_any("**/*.rs", files), false)
    }

    is_path_separator

    fn is_path_separator(c : Char) -> Bool

    Return whether c is a supported path separator.

    Both Unix (/) and Windows (\) separators are recognized.

    Example

    test {
    assert_eq(@glob.is_path_separator('/'), true)
    assert_eq(@glob.is_path_separator('\\'), true)
    assert_eq(@glob.is_path_separator('a'), false)
    }

    is_valid_pattern

    fn is_valid_pattern(pattern : String) -> Bool

    Check whether pattern is structurally valid.

    The current validation is intentionally small in scope: it only checks that [ and ] are balanced. It does not validate or implement the full glob grammar.

    Example

    test {
    assert_eq(@glob.is_valid_pattern("*.mbt"), true)
    assert_eq(@glob.is_valid_pattern("[abc]*.txt"), true)
    assert_eq(@glob.is_valid_pattern("[abc*.txt"), false)
    assert_eq(@glob.is_valid_pattern("abc]*.txt"), false)
    }

    match_any_pattern

    fn match_any_pattern(patterns : Array[String], path : String) -> Bool

    Return whether path matches at least one glob in patterns.

    This is useful when several include rules should be checked together.

    Example

    test {
    let patterns = ["*.md", "**/*.mbt"]
    assert_eq(@glob.match_any_pattern(patterns, "README.md"), true)
    assert_eq(@glob.match_any_pattern(patterns, "src/main.mbt"), true)
    assert_eq(@glob.match_any_pattern(patterns, "package.json"), false)
    }

    match_char

    fn match_char(pattern : Char, char : Char) -> Bool

    Match one pattern character against one text character.

    ? matches any single character. All other characters must be equal.

    Example

    test {
    assert_eq(@glob.match_char('a', 'a'), true)
    assert_eq(@glob.match_char('?', 'x'), true)
    assert_eq(@glob.match_char('a', 'b'), false)
    }

    match_here

    fn match_here(pattern : String, text : String) -> Bool

    Match pattern against text using the package's recursive glob rules.

    This is the low-level matcher that powers glob. Most callers should use glob directly.

    Matching rules:

    • ** can consume any suffix, including path separators
    • * can consume any suffix until the next path separator
    • ? matches exactly one character
    • every other character matches literally

    Example

    test {
    assert_eq(@glob.match_here("**/*.mbt", "src/lib/main.mbt"), true)
    assert_eq(@glob.match_here("*.mbt", "src/lib/main.mbt"), false)
    }

    Source Files

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    © 2026 mooncakes.io