v2 / cmd / tools / modules / scripting / scripting.v
200 lines · 178 sloc · 4.55 KB · 2332ecff4811b8c97dfda8e825170e9397962519
Raw
1module scripting
2
3import os
4import term
5import time
6
7const term_colors = term.can_show_color_on_stdout()
8
9pub fn set_verbose(on bool) {
10 // setting a global here would be the obvious solution,
11 // but V does not have globals normally.
12 if on {
13 os.setenv('VERBOSE', '1', true)
14 } else {
15 os.unsetenv('VERBOSE')
16 }
17}
18
19pub fn cprint(omessage string) {
20 mut message := omessage
21 if term_colors {
22 message = term.cyan(message)
23 }
24 print(message)
25 flush_stdout()
26}
27
28pub fn cprint_strong(omessage string) {
29 mut message := omessage
30 if term_colors {
31 message = term.bright_green(message)
32 }
33 print(message)
34 flush_stdout()
35}
36
37pub fn cprintln(omessage string) {
38 cprint(omessage)
39 println('')
40 flush_stdout()
41}
42
43pub fn cprintln_strong(omessage string) {
44 cprint_strong(omessage)
45 println('')
46 flush_stdout()
47}
48
49pub fn verbose_trace(label string, message string) {
50 if os.getenv('VERBOSE').len > 0 {
51 slabel := '${time.now().format_ss_milli()} ${label}'
52 cprintln('# ${slabel:-43s} : ${message}')
53 }
54}
55
56pub fn verbose_trace_strong(label string, omessage string) {
57 if os.getenv('VERBOSE').len > 0 {
58 slabel := '${time.now().format_ss_milli()} ${label}'
59 mut message := omessage
60 if term_colors {
61 message = term.bright_green(message)
62 }
63 cprintln('# ${slabel:-43s} : ${message}')
64 }
65}
66
67pub fn verbose_trace_exec_result(x os.Result) {
68 if os.getenv('VERBOSE').len > 0 {
69 cprintln('# cmd.exit_code : ${x.exit_code.str():-4s} cmd.output:')
70 mut lnum := 1
71 lines := x.output.split_into_lines()
72 for oline in lines {
73 mut line := oline
74 if term_colors {
75 line = term.bright_green(line)
76 }
77 cprintln('# ${lnum:3d}: ${line}')
78 lnum++
79 }
80 cprintln('# ----------------------------------------------------------------------')
81 }
82}
83
84fn modfn(mname string, fname string) string {
85 return '${mname}.${fname}'
86}
87
88pub fn chdir(path string) {
89 verbose_trace_strong(modfn(@MOD, @FN), 'cd ${path}')
90 os.chdir(path) or {
91 verbose_trace(modfn(@MOD, @FN), '## failed.')
92 return
93 }
94}
95
96pub fn mkdir(path string) ! {
97 verbose_trace_strong(modfn(@MOD, @FN), 'mkdir ${path}')
98 os.mkdir(path) or {
99 verbose_trace(modfn(@MOD, @FN), '## failed.')
100 return err
101 }
102}
103
104pub fn mkdir_all(path string) ! {
105 verbose_trace_strong(modfn(@MOD, @FN), 'mkdir -p ${path}')
106 os.mkdir_all(path) or {
107 verbose_trace(modfn(@MOD, @FN), '## failed.')
108 return err
109 }
110}
111
112pub fn rmrf(path string) {
113 verbose_trace_strong(modfn(@MOD, @FN), 'rm -rf ${path}')
114 if os.exists(path) {
115 if os.is_dir(path) {
116 os.rmdir_all(path) or { panic(err) }
117 } else {
118 os.rm(path) or { panic(err) }
119 }
120 }
121}
122
123// execute a command, and return a result, or an error, if it failed in any way.
124pub fn exec(cmd string) !os.Result {
125 verbose_trace_strong(modfn(@MOD, @FN), cmd)
126 x := os.execute(cmd)
127 if x.exit_code != 0 {
128 verbose_trace(modfn(@MOD, @FN), '## failed.')
129 return error(x.output)
130 }
131 verbose_trace_exec_result(x)
132 return x
133}
134
135// run a command, tracing its results, and returning ONLY its output
136pub fn run(cmd string) string {
137 verbose_trace_strong(modfn(@MOD, @FN), cmd)
138 x := os.execute(cmd)
139 if x.exit_code < 0 {
140 verbose_trace(modfn(@MOD, @FN), '## failed.')
141 return ''
142 }
143 verbose_trace_exec_result(x)
144 if x.exit_code == 0 {
145 return x.output.trim_right('\r\n')
146 }
147 return ''
148}
149
150// frun runs a command, tracing its results, and returning ONLY its output, or an error, if it failed
151pub fn frun(cmd string) !string {
152 verbose_trace_strong(modfn(@MOD, @FN), cmd)
153 x := os.execute(cmd)
154 if x.exit_code != 0 {
155 verbose_trace(modfn(@MOD, @FN), '## failed.')
156 verbose_trace(modfn(@MOD, @FN), '## failure code: ${x.exit_code}')
157 verbose_trace(modfn(@MOD, @FN), '## failure output: ${x.output}')
158 return error_with_code('failed cmd: ${cmd}', x.exit_code)
159 }
160 verbose_trace_exec_result(x)
161 return x.output.trim_right('\r\n')
162}
163
164pub fn exit_0_status(cmd string) bool {
165 verbose_trace_strong(modfn(@MOD, @FN), cmd)
166 x := os.execute(cmd)
167 if x.exit_code < 0 {
168 verbose_trace(modfn(@MOD, @FN), '## failed.')
169 return false
170 }
171 verbose_trace_exec_result(x)
172 if x.exit_code == 0 {
173 return true
174 }
175 return false
176}
177
178pub fn tool_must_exist(toolcmd string) {
179 verbose_trace(modfn(@MOD, @FN), toolcmd)
180 where_is_cmd := if os.user_os() == 'windows' { 'where' } else { 'type' }
181 if exit_0_status('${where_is_cmd} ${toolcmd}') {
182 return
183 }
184 eprintln('Missing tool: ${toolcmd}')
185 eprintln('Please try again after you install it.')
186 exit(1)
187}
188
189pub fn used_tools_must_exist(tools []string) {
190 for t in tools {
191 tool_must_exist(t)
192 }
193}
194
195pub fn show_sizes_of_files(files []string) {
196 for f in files {
197 size := os.file_size(f)
198 println('${size} ${f}') // println('${size:10d} ${f}')
199 }
200}
201