aboutsummaryrefslogtreecommitdiff
path: root/nomnom/files.nom
blob: a17ec85c1a450ccab96678d3185f4e27de7dc776 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# Some file utilities for searching for files recursively and using package.nomsupath
use "lib/os.nom"

%_SPOOFED_FILES = {}
%_FILE_CACHE = ({} with fallback %_SPOOFED_FILES)
%_BROWSE_CACHE = {}

# Create a fake file and put it in the cache
action [spoof file %filename %contents]:
    %_SPOOFED_FILES.%filename = %contents
    return %contents

# Read a file's contents
action [read file %filename]:
    %contents = %_FILE_CACHE.%filename
    if %contents: return %contents
    if (%filename == "stdin"):
        return (spoof file "stdin" (=lua "io.read('*a')"))
    %file = (=lua "io.open(\%filename)")
    unless %file: return (nil)
    %contents = (call %file.read with [%file, "*a"])
    %file::close
    %_FILE_CACHE.%filename = %contents
    return %contents

action [%path sanitized]:
    %path = (%path::with "\\" -> "\\\\")
    %path = (%path::with "`" -> "")
    %path = (%path::with "\"" -> "\\\"")
    %path = (%path::with "$" -> "")
    %path = (%path::with "%.%." -> "\\..")
    return %path

try:
    %lfs = (=lua "require('lfs')")
..and if it succeeds:
    local action [filesystem has %filename]:
        %mode = (call %lfs.attributes with [%filename, "mode"])
        if %mode is:
            ("file", "directory", "link", "char device"):
                return (yes)
            else: return (no)
    
    action [file %path exists]:
        if (..)
            any of [..]
                %_SPOOFED_FILES.%path
                %path == "stdin"
                filesystem has %path
        ..: return (yes)
        for %nomsupath in (%package.nomsupath::all matches of "[^;]+"):
            if (filesystem has "\%nomsupath/\%path"):
                return (yes)
        return (no)

    action [files in %path]:
        unless %_BROWSE_CACHE.%path:
            if (%_SPOOFED_FILES.%path or (%filename == "stdin")):
                %_BROWSE_CACHE.%path = [%path]
            ..else:
                if (call %lfs.attributes with [%filename, "mode"]) is:
                    ("file", "char device"):
                        %_BROWSE_CACHE.%path = [%filename]
                    ("directory", "link"):
                        for %nomsupath in (%package.nomsupath::all matches of "[^;]+"):
                            %files = []
                            for %member in (call %lfs.dir with ["\%nomsupath/\%filename"]):
                                if ((%member == ".") or (%member == "..")):
                                    do next %member
                                for % in (files in %member): %files::add %
                            if ((size of %files) > 0):
                                %_BROWSE_CACHE.%path = %files
                                go to (Found Files)

                        %_BROWSE_CACHE.%path = []
                    else:
                        %_BROWSE_CACHE.%path = []

        === (Found Files) ===
        return %_BROWSE_CACHE.%filename

..or if it barfs:
    # LFS not found! Fall back to shell commands, if available.
    unless (sh> "find . -maxdepth 0"):
        barf "\
            ..Could not find 'luafilesystem' module and couldn't run system command 'find' \
            ..(this might happen on Windows). Please install 'luafilesystem' (which can be \
            ..found at \(..)
                "https://github.com/spacewander/luafilesystem"
                ..if %jit else "https://github.com/keplerproject/luafilesystem"
            .. or obtained through `luarocks install luafilesystem`)"


    action [file %path exists]:
        if (..)
            any of [..]
                %_SPOOFED_FILES.%path
                %path == "stdin"
                sh> "ls \(%path sanitized)"
        ..: return (yes)
        for %nomsupath in (%package.nomsupath::all matches of "[^;]+"):
            if (sh> "ls \(%nomsupath)/\(%path)"):
                return (yes)
        return (no)

    action [files in %path]:
        unless %_BROWSE_CACHE.%path:
            if %_SPOOFED_FILES.%path:
                %_BROWSE_CACHE.%path = [%_SPOOFED_FILES.%path]
            ..else:
                for %nomsupath in (%package.nomsupath::all matches of "[^;]+"):
                    %files = (sh> "find -L '\%path' -not -path '*/\\.*' -type f'")
                    if %files:
                        %_BROWSE_CACHE.%path = (%files::lines)
                        go to (Found Files)
                %_BROWSE_CACHE.%path = []

        === (Found Files) ===
        return %_BROWSE_CACHE.%path