9942 commits 0 issues 0 pull requests 439 contributors 0 branches 0 releases
Additions: 38 Deletions: 4
cmd/tools/vwatch.v
1 silent bool // when true, watch will not print a timestamp line before each re-run
2 add_files []string // path to additional files that have to be watched for changes
3 ignore_exts []string // extensions of files that will be ignored, even if they change (useful for sqlite.db files for example)
4+ cmd_before_run string // a command to run before each re-run
5+ cmd_after_run string // a command to run after each re-run
6 }
7
8 [if debug_vwatch]
9 context.child_process.wait()
10 }
11
12+fn (mut context Context) run_before_cmd() {
13+ if context.cmd_before_run != '' {
14+ context.elog('> run_before_cmd: "$context.cmd_before_run"')
15+ os.system(context.cmd_before_run)
16+ }
17+}
18+
19+fn (mut context Context) run_after_cmd() {
20+ if context.cmd_after_run != '' {
21+ context.elog('> run_after_cmd: "$context.cmd_after_run"')
22+ os.system(context.cmd_after_run)
23+ }
24+}
25+
26 fn (mut context Context) compilation_runner_loop() {
27 cmd := '"$context.vexe" ${context.opts.join(' ')}'
28 _ := <-context.rerun_channel
29 for {
30 context.elog('>> loop: v_cycles: $context.v_cycles')
31+ if context.clear_terminal {
32+ term.clear()
33+ }
34+ context.run_before_cmd()
35 timestamp := time.now().format_ss_milli()
36 context.child_process = os.new_process(context.vexe)
37 context.child_process.use_pgroup = true
38 context.child_process.set_args(context.opts)
39 context.child_process.run()
40- if context.clear_terminal {
41- term.clear()
42- }
43 if !context.silent {
44 eprintln('$timestamp: $cmd | pid: ${context.child_process.pid:7d} | reload cycle: ${context.v_cycles:5d}')
45 }
46 for {
47+ mut notalive_count := 0
48 mut cmds := []RerunCommand{}
49 for {
50 if context.is_exiting {
51 }
52 if !context.child_process.is_alive() {
53 context.child_process.wait()
54+ notalive_count++
55+ if notalive_count == 1 {
56+ // a short lived process finished, do cleanup:
57+ context.run_after_cmd()
58+ }
59 }
60 select {
61 action := <-context.rerun_channel {
62 if !context.child_process.is_alive() {
63 context.child_process.wait()
64 context.child_process.close()
65+ if notalive_count == 0 {
66+ // a long running process was killed, do cleanup:
67+ context.run_after_cmd()
68+ }
69 break
70 }
71 }
72 context.is_worker = fp.bool('vwatchworker', 0, false, 'Internal flag. Used to distinguish vwatch manager and worker processes.')
73 context.silent = fp.bool('silent', `s`, false, 'Be more silent; do not print the watch timestamp before each re-run.')
74 context.clear_terminal = fp.bool('clear', `c`, false, 'Clears the terminal before each re-run.')
75- context.add_files = fp.string('add', `a`, '', 'Add more files to be watched. Useful with `v watch -add=/tmp/feature.v run cmd/v /tmp/feature.v`, when you want to change *both* the compiler, and the feature.v file.').split(',')
76+ context.add_files = fp.string('add', `a`, '', 'Add more files to be watched. Useful with `v watch -add=/tmp/feature.v run cmd/v /tmp/feature.v`, if you change *both* the compiler, and the feature.v file.').split(',')
77 context.ignore_exts = fp.string('ignore', `i`, '', 'Ignore files having these extensions. Useful with `v watch -ignore=.db run server.v`, if your server writes to an sqlite.db file in the same folder.').split(',')
78 show_help := fp.bool('help', `h`, false, 'Show this help screen.')
79+ context.cmd_before_run = fp.string('before', 0, '', 'A command to execute *before* each re-run.')
80+ context.cmd_after_run = fp.string('after', 0, '', 'A command to execute *after* each re-run.')
81 if show_help {
82 println(fp.usage())
83 exit(0)
84
cmd/v/help/watch.txt
1 Useful with `v watch -ignore=.db run vwebserver.v`,
2 if your `vwebserver` writes to an sqlite.db file in the
3 same folder.
4+
5+ --before <string> A command to execute *before* each re-run. Example: --before 'v wipe-cache'
6+
7+ --after <string> A command to execute *after* each re-run. Example: --after 'rm -rf /tmp/v/'
8+
9