-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathpath.moon
More file actions
146 lines (113 loc) · 3.36 KB
/
path.moon
File metadata and controls
146 lines (113 loc) · 3.36 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
io = io
needs_shell_escape = (str) ->
not not str\match "[^%w_-]"
shell_escape = (str) ->
str\gsub "'", "'\\''"
local *
-- move up a directory
-- /hello/world -> /hello
up = (path) ->
path = path\gsub "/$", ""
path = path\gsub "[^/]*$", ""
path if path != ""
exists = (path) ->
file = io.open path
file\close! and true if file
normalize = (path) ->
(path\gsub "^%./", "")
basepath = (path) ->
(path\match"^(.*)/[^/]*$" or ".")
filename = (path) ->
(path\match"([^/]*)$")
-- write a file, making sure directory exists and file isn't already written
write_file_safe = (path, content, check_exists=false) ->
if check_exists and exists path
return nil, "file already exists `#{path}`"
if prefix = path\match "^(.+)/[^/]+$"
mkdir prefix unless exists prefix
write_file path, content
true
write_file = (path, content) ->
assert content, "trying to write `#{path}` with no content"
with io.open path, "w"
\write content
\close!
read_file = (path) ->
file = io.open path
error "file doesn't exist `#{path}'" unless file
with file\read "*a"
file\close!
mkdir = (path) ->
os.execute "mkdir -p '#{shell_escape path}'"
rmdir = (path) ->
os.execute "rm -r '#{shell_escape path}'"
copy = (src, dest) ->
os.execute "cp '#{shell_escape src}' '#{shell_escape dest}'"
join = (a, b) ->
assert a, "missing left argument to Path.join"
assert b, "missing right argument to Path.join"
a = a\match"^(.*)/$" or a if a != "/"
b = b\match"^/(.*)$" or b
return b if a == ""
return a if b == ""
a .. "/" .. b
_prepare_command = (cmd, ...) ->
args = for x in *{...}
if needs_shell_escape x
"'#{shell_escape x}'"
else
x
args = table.concat args, " "
"#{cmd} #{args}"
exec = (cmd, ...) ->
os.execute _prepare_command cmd, ...
read_exec = (cmd, ...) ->
f = assert io.popen _prepare_command(cmd, ...), "r"
with f\read "*a"
f\close!
relative_to = (prefix) =>
methods = {"mkdir", "read_file", "write_file", "write_file_safe", "exists"}
prefixed = (fn) ->
(path, ...) ->
@[fn] @.join(prefix, path), ...
m = setmetatable {meth, prefixed(meth) for meth in *methods}, {
__index: @
}
m.full_path = (path) -> @.join prefix, path
m.strip_prefix = (path) ->
import escape_patt from require "sitegen.common"
path\gsub "^#{escape_patt prefix}/?", ""
m.get_prefix = -> prefix
m.set_prefix = (p) -> prefix = p
m
annotate = =>
wrap_module = (obj, verbs) ->
setmetatable {}, {
__newindex: (name, value) =>
obj[name] = value
__index: (name) =>
fn = obj[name]
return fn if not type(fn) == "function"
if verbs[name]
(...) ->
print verbs[name], (...)
fn ...
else
fn
}
colors = require "ansicolors"
wrap_module @, {
mkdir: colors "%{bright}%{magenta}made directory%{reset}"
write_file: colors "%{bright}%{yellow}wrote%{reset}"
write_file_safe: colors "%{bright}%{yellow}wrote%{reset}"
read_file: colors "%{bright}%{green}read%{reset}"
exists: colors "%{bright}%{cyan}exists?%{reset}"
exec: colors "%{bright}%{red}exec%{reset}"
read_exec: colors "%{bright}%{red}exec%{reset}"
}
{
:up, :exists, :normalize, :basepath, :filename, :write_file,
:write_file_safe, :mkdir, :rmdir, :copy, :join, :read_file, :shell_escape,
:exec, :read_exec
:relative_to, :annotate
}